Compare commits
17 Commits
ServiceAmo
...
Feature/pr
| Author | SHA1 | Date | |
|---|---|---|---|
| aa37ca4b28 | |||
| 45615684ed | |||
| 94955ea1b4 | |||
| 656bb49fab | |||
| fb5b98bf25 | |||
| 1e733f3f20 | |||
| d855684cd7 | |||
| 9e5e8d8e5d | |||
| 9eefdd8fd1 | |||
| 2159901614 | |||
| 7ce7854091 | |||
| 4c638cbdae | |||
| 39a5918a11 | |||
| b9e271de1a | |||
| e661bc2dcb | |||
| 1bfe41418b | |||
| 6a446d5972 |
@@ -0,0 +1,49 @@
|
||||
using GozareshgirProgramManager.Application._Common.Interfaces;
|
||||
using GozareshgirProgramManager.Application._Common.Models;
|
||||
using GozareshgirProgramManager.Domain._Common;
|
||||
using GozareshgirProgramManager.Domain.ProjectAgg.Enums;
|
||||
using GozareshgirProgramManager.Domain.ProjectAgg.Repositories;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.AutoStopOverTimeTaskSections;
|
||||
|
||||
public record AutoStopOverTimeTaskSectionsCommand : IBaseCommand;
|
||||
|
||||
public class AutoStopOverTimeTaskSectionsCommandHandler : IBaseCommandHandler<AutoStopOverTimeTaskSectionsCommand>
|
||||
{
|
||||
private readonly ITaskSectionRepository _taskSectionRepository;
|
||||
private readonly IUnitOfWork _unitOfWork;
|
||||
|
||||
public AutoStopOverTimeTaskSectionsCommandHandler(ITaskSectionRepository taskSectionRepository,
|
||||
IUnitOfWork unitOfWork)
|
||||
{
|
||||
_taskSectionRepository = taskSectionRepository;
|
||||
_unitOfWork = unitOfWork;
|
||||
}
|
||||
|
||||
public async Task<OperationResult> Handle(AutoStopOverTimeTaskSectionsCommand request,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
// دریافت تمام تسکهای در حال انجام
|
||||
var taskSections = await _taskSectionRepository.GetActiveSectionsIncludeAllAsync(cancellationToken);
|
||||
|
||||
|
||||
foreach (var taskSection in taskSections)
|
||||
{
|
||||
// استفاده از متد Domain برای بررسی و متوقف کردن خودکار
|
||||
taskSection.AutoStopIfOverTime();
|
||||
}
|
||||
|
||||
// ذخیره تغییرات در دیتابیس
|
||||
await _unitOfWork.SaveChangesAsync(cancellationToken);
|
||||
|
||||
return OperationResult.Success();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return OperationResult.Failure($"خطا در ناتمام کردن تسکهای overtime: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
using System.Linq;
|
||||
using GozareshgirProgramManager.Application._Common.Interfaces;
|
||||
using GozareshgirProgramManager.Application._Common.Models;
|
||||
using GozareshgirProgramManager.Domain.ProjectAgg.Entities;
|
||||
using GozareshgirProgramManager.Domain.ProjectAgg.Enums;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.AutoUpdateDeployStatus;
|
||||
|
||||
public record AutoUpdateDeployStatusCommand : IBaseCommand;
|
||||
|
||||
public class AutoUpdateDeployStatusCommandHandler : IBaseCommandHandler<AutoUpdateDeployStatusCommand>
|
||||
{
|
||||
private readonly IProgramManagerDbContext _dbContext;
|
||||
|
||||
public AutoUpdateDeployStatusCommandHandler(IProgramManagerDbContext dbContext)
|
||||
{
|
||||
_dbContext = dbContext;
|
||||
}
|
||||
|
||||
public async Task<OperationResult> Handle(AutoUpdateDeployStatusCommand request,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
// Fetch all sections whose phase is still marked as not completed
|
||||
var sections = await _dbContext.TaskSections
|
||||
.Include(ts => ts.Task)
|
||||
.ThenInclude(t => t.Phase)
|
||||
.Where(ts => ts.Task.Phase.DeployStatus == ProjectDeployStatus.NotCompleted)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
if (sections.Count == 0)
|
||||
return OperationResult.Success();
|
||||
|
||||
var phasesToUpdate = sections
|
||||
.GroupBy(ts => ts.Task.PhaseId)
|
||||
.Where(g => g.All(s => s.Status == TaskSectionStatus.Completed))
|
||||
.Select(g => g.First().Task.Phase)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
|
||||
if (phasesToUpdate.Count == 0)
|
||||
return OperationResult.Success();
|
||||
|
||||
foreach (var phase in phasesToUpdate)
|
||||
{
|
||||
phase.UpdateDeployStatus(ProjectDeployStatus.PendingDevDeploy);
|
||||
}
|
||||
|
||||
await _dbContext.SaveChangesAsync(cancellationToken);
|
||||
return OperationResult.Success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using GozareshgirProgramManager.Application._Common.Interfaces;
|
||||
using GozareshgirProgramManager.Application._Common.Models;
|
||||
using GozareshgirProgramManager.Domain._Common;
|
||||
using GozareshgirProgramManager.Domain.ProjectAgg.Entities;
|
||||
using GozareshgirProgramManager.Domain.ProjectAgg.Repositories;
|
||||
|
||||
namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.ChangeDeployStatusProject;
|
||||
|
||||
public record ChangeDeployStatusProjectCommand(Guid PhaseId, ProjectDeployStatus Status):IBaseCommand;
|
||||
|
||||
public class ChangeDeployStatusProjectCommandHandler : IBaseCommandHandler<ChangeDeployStatusProjectCommand>
|
||||
{
|
||||
private readonly IProjectRepository _projectRepository;
|
||||
private readonly IProjectPhaseRepository _projectPhaseRepository;
|
||||
private readonly IUnitOfWork _unitOfWork;
|
||||
|
||||
public ChangeDeployStatusProjectCommandHandler(IProjectRepository projectRepository, IUnitOfWork unitOfWork, IProjectPhaseRepository projectPhaseRepository)
|
||||
{
|
||||
_projectRepository = projectRepository;
|
||||
_unitOfWork = unitOfWork;
|
||||
_projectPhaseRepository = projectPhaseRepository;
|
||||
}
|
||||
|
||||
public async Task<OperationResult> Handle(ChangeDeployStatusProjectCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var project = await _projectPhaseRepository.GetByIdAsync(request.PhaseId, cancellationToken);
|
||||
if (project == null)
|
||||
return OperationResult.NotFound("بخش مورد نظر یافت نشد");
|
||||
|
||||
if (project.DeployStatus == ProjectDeployStatus.NotCompleted)
|
||||
{
|
||||
return OperationResult.Failure("وضعیت استقرار نمیتواند از حالت 'تایید نشده' تغییر کند.");
|
||||
}
|
||||
|
||||
if (request.Status == ProjectDeployStatus.NotCompleted)
|
||||
{
|
||||
return OperationResult.Failure("وضعیت استقرار نمیتواند به حالت 'تایید نشده' تغییر کند.");
|
||||
}
|
||||
project.UpdateDeployStatus(request.Status);
|
||||
|
||||
await _unitOfWork.SaveChangesAsync(cancellationToken);
|
||||
return OperationResult.Success();
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Globalization;
|
||||
using GozareshgirProgramManager.Application._Common.Interfaces;
|
||||
using GozareshgirProgramManager.Application._Common.Models;
|
||||
using GozareshgirProgramManager.Domain._Common;
|
||||
@@ -7,21 +8,23 @@ namespace GozareshgirProgramManager.Application.Modules.Projects.Queries.Project
|
||||
|
||||
public record ProjectBoardDetailQuery(Guid SectionId) : IBaseQuery<ProjectBoardDetailResponse>;
|
||||
|
||||
public record ProjectBoardDetailResponse(List<ProjectBoardDetailUserResponse> Users, string TotalTime);
|
||||
public record ProjectBoardDetailResponse(List<ProjectBoardDetailUserResponse> Users, string TotalTime,string RemainingTime );
|
||||
|
||||
public record ProjectBoardDetailUserResponse
|
||||
{
|
||||
public List<ProjectBoardDetailUserHistoryResponse> Histories { get; set; } = new();
|
||||
public string UserFullName { get; set; }
|
||||
public long UserId { get; set; }
|
||||
public List<ProjectBoardDetailUserHistoryResponse> Histories { get; init; }
|
||||
public string UserFullName { get; init; }
|
||||
public string TotalTime { get; init; }
|
||||
public string SpentTime { get; init; }
|
||||
public long UserId { get; init; }
|
||||
}
|
||||
|
||||
public class ProjectBoardDetailUserHistoryResponse
|
||||
public record ProjectBoardDetailUserHistoryResponse
|
||||
{
|
||||
public string Date { get; set; }
|
||||
public string startTime { get; set; }
|
||||
public string EndTime { get; set; }
|
||||
public string TotalTime { get; set; }
|
||||
public string Date { get; init; }
|
||||
public string startTime { get; init; }
|
||||
public string EndTime { get; init; }
|
||||
public string TotalTime { get; init; }
|
||||
}
|
||||
|
||||
public class ProjectBoardDetailQueryHandler : IBaseQueryHandler<ProjectBoardDetailQuery, ProjectBoardDetailResponse>
|
||||
@@ -38,6 +41,7 @@ public class ProjectBoardDetailQueryHandler : IBaseQueryHandler<ProjectBoardDeta
|
||||
{
|
||||
var section = await _programManagerDbContext.TaskSections
|
||||
.Include(x => x.Activities)
|
||||
.Include(x=>x.AdditionalTimes)
|
||||
.FirstOrDefaultAsync(x => x.Id == request.SectionId, cancellationToken: cancellationToken);
|
||||
|
||||
if (section == null)
|
||||
@@ -49,16 +53,22 @@ public class ProjectBoardDetailQueryHandler : IBaseQueryHandler<ProjectBoardDeta
|
||||
.Where(x => userIds.Contains(x.Id))
|
||||
.ToDictionaryAsync(x => x.Id, x => x.FullName, cancellationToken);
|
||||
|
||||
var totalTimeSpan = section.Activities
|
||||
var totalActivityTimeSpan = section.Activities
|
||||
.Select(x => x.GetTimeSpent())
|
||||
.Aggregate(TimeSpan.Zero, (sum, next) => sum.Add(next));
|
||||
|
||||
var finalTime = section.FinalEstimatedHours;
|
||||
|
||||
var remainingTimeSpan = finalTime >= totalActivityTimeSpan
|
||||
? TimeSpan.FromTicks(finalTime.Ticks - totalActivityTimeSpan.Ticks)
|
||||
: TimeSpan.Zero;
|
||||
var users = section.Activities.GroupBy(x => x.UserId).Select(x =>
|
||||
{
|
||||
return new ProjectBoardDetailUserResponse()
|
||||
{
|
||||
UserId = x.Key,
|
||||
UserFullName = usersDict[x.Key],
|
||||
TotalTime = TimeSpan.FromTicks(x.Sum(h=>h.GetTimeSpent().Ticks)).TotalHours.ToString(CultureInfo.InvariantCulture),
|
||||
Histories = x.Select(h => new ProjectBoardDetailUserHistoryResponse()
|
||||
{
|
||||
Date = h.StartDate.ToFarsi(),
|
||||
@@ -68,7 +78,8 @@ public class ProjectBoardDetailQueryHandler : IBaseQueryHandler<ProjectBoardDeta
|
||||
}).ToList()
|
||||
};
|
||||
}).ToList();
|
||||
var response = new ProjectBoardDetailResponse(users, $"{(int)totalTimeSpan.TotalHours}:{totalTimeSpan.Minutes:D2}");
|
||||
var response = new ProjectBoardDetailResponse(users, $"{(int)totalActivityTimeSpan.TotalHours}:{totalActivityTimeSpan.Minutes:D2}",
|
||||
$"{(int)remainingTimeSpan.TotalHours}:{remainingTimeSpan.Minutes:D2}");
|
||||
return OperationResult<ProjectBoardDetailResponse>.Success(response);
|
||||
}
|
||||
}
|
||||
@@ -22,8 +22,9 @@ public class ProjectBoardListQueryHandler : IBaseQueryHandler<ProjectBoardListQu
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var currentUserId = _authHelper.GetCurrentUserId();
|
||||
|
||||
var queryable = _programManagerDbContext.TaskSections.AsNoTracking()
|
||||
.Where(x => 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)
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
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<ProjectDeployBoardDetailTaskItem> Tasks);
|
||||
|
||||
public record ProjectDeployBoardDetailPhaseItem(
|
||||
string Name,
|
||||
TimeSpan TotalTimeSpan,
|
||||
TimeSpan DoneTimeSpan);
|
||||
|
||||
public record ProjectDeployBoardDetailTaskItem(
|
||||
string Name,
|
||||
TimeSpan TotalTimeSpan,
|
||||
TimeSpan DoneTimeSpan,
|
||||
List<ProjectDeployBoardDetailItemSkill> Skills)
|
||||
: ProjectDeployBoardDetailPhaseItem(Name, TotalTimeSpan, DoneTimeSpan);
|
||||
|
||||
public record ProjectDeployBoardDetailItemSkill(string OriginalUserFullName, string SkillName, int TimePercentage);
|
||||
|
||||
public record ProjectDeployBoardDetailsQuery(Guid PhaseId) : IBaseQuery<ProjectDeployBoardDetailsResponse>;
|
||||
|
||||
public class
|
||||
ProjectDeployBoardDetailsQueryHandler : IBaseQueryHandler<ProjectDeployBoardDetailsQuery,
|
||||
ProjectDeployBoardDetailsResponse>
|
||||
{
|
||||
private readonly IProgramManagerDbContext _dbContext;
|
||||
|
||||
public ProjectDeployBoardDetailsQueryHandler(IProgramManagerDbContext dbContext)
|
||||
{
|
||||
_dbContext = dbContext;
|
||||
}
|
||||
|
||||
public async Task<OperationResult<ProjectDeployBoardDetailsResponse>> 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<ProjectDeployBoardDetailsResponse>.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 =>
|
||||
{
|
||||
var originalUserFullName = usersDict.GetValueOrDefault(s.OriginalAssignedUserId,
|
||||
"کاربر ناشناس");
|
||||
|
||||
var skillName = s.Skill?.Name ?? "بدون مهارت";
|
||||
|
||||
var totalTimeSpent = s.GetTotalTimeSpent();
|
||||
|
||||
var timePercentage = s.FinalEstimatedHours.Ticks > 0
|
||||
? (int)((totalTimeSpent.Ticks / (double)s.FinalEstimatedHours.Ticks) * 100)
|
||||
: 0;
|
||||
|
||||
return new ProjectDeployBoardDetailItemSkill(
|
||||
originalUserFullName,
|
||||
skillName,
|
||||
timePercentage);
|
||||
}).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<ProjectDeployBoardDetailsResponse>.Success(res);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using FluentValidation;
|
||||
|
||||
namespace GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectDeployBoardDetail;
|
||||
|
||||
public class ProjectDeployBoardDetailsQueryValidator:AbstractValidator<ProjectDeployBoardDetailsQuery>
|
||||
{
|
||||
public ProjectDeployBoardDetailsQueryValidator()
|
||||
{
|
||||
RuleFor(x=>x.PhaseId).NotNull().WithMessage("شناسه بخش اصلی نمیتواند خالی باشد");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
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 Guid Id { get; set; }
|
||||
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<ProjectDeployBoardListItem> Items);
|
||||
|
||||
|
||||
public record GetProjectDeployBoardListQuery():IBaseQuery<GetProjectsDeployBoardListResponse>;
|
||||
|
||||
public class ProjectDeployBoardListQueryHandler:IBaseQueryHandler<GetProjectDeployBoardListQuery, GetProjectsDeployBoardListResponse>
|
||||
{
|
||||
private readonly IProgramManagerDbContext _dbContext;
|
||||
private readonly IAuthHelper _authHelper;
|
||||
|
||||
|
||||
public ProjectDeployBoardListQueryHandler(IProgramManagerDbContext dbContext, IAuthHelper authHelper)
|
||||
{
|
||||
_dbContext = dbContext;
|
||||
_authHelper = authHelper;
|
||||
}
|
||||
|
||||
public async Task<OperationResult<GetProjectsDeployBoardListResponse>> Handle(GetProjectDeployBoardListQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
var userId = _authHelper.GetCurrentUserId();
|
||||
if (userId == null)
|
||||
{
|
||||
return OperationResult<GetProjectsDeployBoardListResponse>.NotFound("کاربر یافت نشد");
|
||||
}
|
||||
|
||||
var query =await _dbContext.TaskSections
|
||||
.Include(x=>x.Activities)
|
||||
.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
|
||||
&& x.InitialEstimatedHours>TimeSpan.Zero))
|
||||
.GroupBy(x=>x.Task.PhaseId).ToListAsync(cancellationToken: cancellationToken);
|
||||
|
||||
var list = query.Select(g => new ProjectDeployBoardListItem
|
||||
{
|
||||
Id = g.Key,
|
||||
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.FromTicks(g.Sum(x => x.InitialEstimatedHours.Ticks)),
|
||||
DoneTimeSpan = TimeSpan.FromTicks(g.Sum(x=>x.GetTotalTimeSpent().Ticks)),
|
||||
DeployStatus = g.First().Task.Phase.DeployStatus
|
||||
}).ToList();
|
||||
var response = new GetProjectsDeployBoardListResponse(list);
|
||||
return OperationResult<GetProjectsDeployBoardListResponse>.Success(response);
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@ public class ProjectPhase : ProjectHierarchyNode
|
||||
ProjectId = projectId;
|
||||
_tasks = new List<ProjectTask>();
|
||||
_phaseSections = new List<PhaseSection>();
|
||||
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,30 @@ public class ProjectPhase : ProjectHierarchyNode
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void SetArchived()
|
||||
{
|
||||
IsArchived = true;
|
||||
}
|
||||
public void SetUnarchived()
|
||||
{
|
||||
IsArchived = false;
|
||||
}
|
||||
public void UpdateDeployStatus(ProjectDeployStatus status)
|
||||
{
|
||||
DeployStatus = status;
|
||||
if (status == ProjectDeployStatus.Deployed)
|
||||
{
|
||||
IsArchived = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum ProjectDeployStatus
|
||||
{
|
||||
NotCompleted,
|
||||
PendingDevDeploy,
|
||||
DevDeployed,
|
||||
PendingDeploy,
|
||||
Deployed
|
||||
}
|
||||
|
||||
@@ -217,4 +217,39 @@ public class TaskSection : EntityBase<Guid>
|
||||
var finalEstimate = FinalEstimatedHours;
|
||||
return totalSpent < finalEstimate;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// اگر زمان کار شده بیش از تایم تعیین شده باشد، تسک را متوقف میکند
|
||||
/// و EndDate را به طوری تنظیم میکند که کل زمان برابر با FinalEstimatedHours شود
|
||||
/// </summary>
|
||||
public void AutoStopIfOverTime()
|
||||
{
|
||||
if (Status != TaskSectionStatus.InProgress)
|
||||
return;
|
||||
|
||||
var activeActivity = _activities.FirstOrDefault(a => a.IsActive);
|
||||
if (activeActivity == null)
|
||||
return;
|
||||
|
||||
// محاسبه کل زمان صرف شده تا کنون (بدون فعالیت فعال)
|
||||
var totalTimeSpentExcludingActive = _activities.Where(a => !a.IsActive).Sum(a => a.GetTimeSpent().Ticks);
|
||||
var totalTimeSpentTimeSpan = TimeSpan.FromTicks(totalTimeSpentExcludingActive);
|
||||
var finalEstimate = FinalEstimatedHours;
|
||||
|
||||
// اگر زمان صرف شده (بدون فعالیت فعال) + فعالیت فعال > تایم تعیین شده
|
||||
var activeTimeSpent = activeActivity.GetTimeSpent();
|
||||
if (totalTimeSpentTimeSpan + activeTimeSpent > finalEstimate)
|
||||
{
|
||||
// محاسبه مدت زمانی که این فعالیت باید برای رسیدن به FinalEstimatedHours داشته باشد
|
||||
var remainingTime = finalEstimate - totalTimeSpentTimeSpan;
|
||||
|
||||
// EndDate = StartDate + remainingTime
|
||||
var adjustedEndDate = activeActivity.StartDate.Add(remainingTime);
|
||||
|
||||
// متوقف کردن فعالیت با EndDate دقیق شده
|
||||
activeActivity.StopWorkWithSpecificTime(adjustedEndDate, "متوقف خودکار - بیش از تایم تعیین شده");
|
||||
|
||||
UpdateStatus(TaskSectionStatus.Incomplete);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -40,6 +40,22 @@ public class TaskSectionActivity : EntityBase<Guid>
|
||||
IsActive = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// متوقف کردن فعالیت با مشخص کردن EndDate دقیق
|
||||
/// </summary>
|
||||
public void StopWorkWithSpecificTime(DateTime endDate, string? endNotes = null)
|
||||
{
|
||||
if (!IsActive)
|
||||
throw new InvalidOperationException("این فعالیت قبلاً متوقف شده است.");
|
||||
|
||||
if (endDate < StartDate)
|
||||
throw new InvalidOperationException("تاریخ پایان نمیتواند قبل از تاریخ شروع باشد.");
|
||||
|
||||
EndDate = endDate;
|
||||
EndNotes = endNotes;
|
||||
IsActive = false;
|
||||
}
|
||||
|
||||
public TimeSpan GetTimeSpent()
|
||||
{
|
||||
if (IsActive)
|
||||
|
||||
@@ -6,5 +6,6 @@ public enum TaskSectionStatus
|
||||
ReadyToStart = 1, // آماده شروع
|
||||
InProgress = 2, // درحال انجام
|
||||
Incomplete = 3, // ناتمام شده
|
||||
Completed = 4 // تکمیل شده
|
||||
PendingForCompletion = 4, // در انتظار تکمیل
|
||||
Completed = 5 // تکمیل شده
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ namespace GozareshgirProgramManager.Domain.ProjectAgg.Repositories;
|
||||
|
||||
public interface ITaskSectionActivityRepository:IRepository<Guid,TaskSectionActivity>
|
||||
{
|
||||
Task<TaskSectionActivity?> GetByIdAsync(Guid id);
|
||||
Task<List<TaskSectionActivity>> GetBySectionIdAsync(Guid sectionId);
|
||||
Task<List<TaskSectionActivity>> GetByUserIdAsync(long userId);
|
||||
Task<List<TaskSectionActivity>> GetActiveByUserAsync(long userId);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Collections;
|
||||
using GozareshgirProgramManager.Domain._Common;
|
||||
using GozareshgirProgramManager.Domain.ProjectAgg.Entities;
|
||||
|
||||
@@ -11,4 +12,5 @@ public interface ITaskSectionRepository: IRepository<Guid,TaskSection>
|
||||
Task<TaskSection?> GetByIdWithFullDataAsync(Guid id, CancellationToken cancellationToken = default);
|
||||
|
||||
Task<List<TaskSection>> GetAssignedToUserAsync(long userId);
|
||||
Task<List<TaskSection>> GetActiveSectionsIncludeAllAsync(CancellationToken cancellationToken);
|
||||
}
|
||||
@@ -5,7 +5,7 @@ namespace GozareshgirProgramManager.Domain._Common;
|
||||
public interface IRepository<TKey, T> where T:class
|
||||
{
|
||||
T Get(TKey id);
|
||||
Task<T?> GetByIdAsync(TKey id);
|
||||
Task<T?> GetByIdAsync(TKey id, CancellationToken cancellationToken = default);
|
||||
List<T> Get();
|
||||
IQueryable<T> GetQueryable();
|
||||
void Create(T entity);
|
||||
|
||||
@@ -0,0 +1,865 @@
|
||||
// <auto-generated />
|
||||
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
|
||||
{
|
||||
/// <inheritdoc />
|
||||
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<Guid>("Id")
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<DateTime>("CheckoutEndDate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<DateTime>("CheckoutStartDate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<DateTime>("CreationDate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<double>("DeductionFromSalary")
|
||||
.HasColumnType("float");
|
||||
|
||||
b.Property<string>("FullName")
|
||||
.IsRequired()
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("nvarchar(100)");
|
||||
|
||||
b.Property<int>("MandatoryHours")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("Month")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<double>("MonthlySalaryDefined")
|
||||
.HasColumnType("float");
|
||||
|
||||
b.Property<double>("MonthlySalaryPay")
|
||||
.HasColumnType("float");
|
||||
|
||||
b.Property<int>("RemainingHours")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("TotalDaysWorked")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("TotalHoursWorked")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<long>("UserId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<int>("Year")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Checkouts", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GozareshgirProgramManager.Domain.CustomerAgg.Customer", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<DateTime>("CreationDate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("nvarchar(256)");
|
||||
|
||||
b.Property<string>("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<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<DateTime>("CreationDate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<Guid>("PhaseId")
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<Guid>("SkillId")
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<long>("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<Guid>("Id")
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<DateTime>("CreationDate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasMaxLength(1000)
|
||||
.HasColumnType("nvarchar(1000)");
|
||||
|
||||
b.Property<DateTime?>("EndDate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<bool>("HasAssignmentOverride")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(200)
|
||||
.HasColumnType("nvarchar(200)");
|
||||
|
||||
b.Property<DateTime?>("PlannedEndDate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<DateTime?>("PlannedStartDate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<DateTime?>("StartDate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<string>("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<Guid>("Id")
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<DateTime>("CreationDate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<string>("DeployStatus")
|
||||
.IsRequired()
|
||||
.HasMaxLength(30)
|
||||
.HasColumnType("nvarchar(30)");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasMaxLength(1000)
|
||||
.HasColumnType("nvarchar(1000)");
|
||||
|
||||
b.Property<DateTime?>("EndDate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<bool>("HasAssignmentOverride")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<bool>("IsArchived")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(200)
|
||||
.HasColumnType("nvarchar(200)");
|
||||
|
||||
b.Property<int>("OrderIndex")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<Guid>("ProjectId")
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<DateTime?>("StartDate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<string>("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<Guid>("Id")
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<DateTime>("CreationDate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<Guid>("ProjectId")
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<Guid>("SkillId")
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<long>("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<Guid>("Id")
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<string>("AllocatedTime")
|
||||
.HasMaxLength(30)
|
||||
.HasColumnType("nvarchar(30)");
|
||||
|
||||
b.Property<DateTime>("CreationDate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasMaxLength(1000)
|
||||
.HasColumnType("nvarchar(1000)");
|
||||
|
||||
b.Property<DateTime?>("DueDate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<DateTime?>("EndDate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<bool>("HasAssignmentOverride")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<bool>("HasTimeOverride")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(200)
|
||||
.HasColumnType("nvarchar(200)");
|
||||
|
||||
b.Property<int>("OrderIndex")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<Guid>("PhaseId")
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<string>("Priority")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("nvarchar(50)");
|
||||
|
||||
b.Property<DateTime?>("StartDate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<string>("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<Guid>("Id")
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<DateTime>("CreationDate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<long>("CurrentAssignedUserId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<string>("InitialDescription")
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("nvarchar(500)");
|
||||
|
||||
b.Property<string>("InitialEstimatedHours")
|
||||
.IsRequired()
|
||||
.HasMaxLength(30)
|
||||
.HasColumnType("nvarchar(30)");
|
||||
|
||||
b.Property<long>("OriginalAssignedUserId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<Guid>("SkillId")
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<string>("Status")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("nvarchar(50)");
|
||||
|
||||
b.Property<Guid>("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<Guid>("Id")
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<DateTime>("CreationDate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<DateTime?>("EndDate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<string>("EndNotes")
|
||||
.HasMaxLength(1000)
|
||||
.HasColumnType("nvarchar(1000)");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<string>("Notes")
|
||||
.HasMaxLength(1000)
|
||||
.HasColumnType("nvarchar(1000)");
|
||||
|
||||
b.Property<Guid>("SectionId")
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<DateTime>("StartDate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<long>("UserId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("SectionId");
|
||||
|
||||
b.ToTable("TaskSectionActivities", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSectionAdditionalTime", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<DateTime>("AddedAt")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<long?>("AddedByUserId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<DateTime>("CreationDate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<string>("Hours")
|
||||
.IsRequired()
|
||||
.HasMaxLength(30)
|
||||
.HasColumnType("nvarchar(30)");
|
||||
|
||||
b.Property<string>("Reason")
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("nvarchar(500)");
|
||||
|
||||
b.Property<Guid?>("TaskSectionId")
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("TaskSectionId");
|
||||
|
||||
b.ToTable("TaskSectionAdditionalTimes", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GozareshgirProgramManager.Domain.RoleAgg.Entities.Role", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Id"));
|
||||
|
||||
b.Property<DateTime>("CreationDate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<long?>("GozareshgirRoleId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<string>("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<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Id"));
|
||||
|
||||
b.Property<DateTime>("CreationDate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<DateTime?>("EndSettingDate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<bool>("HolidayWorking")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<double>("MonthlySalary")
|
||||
.HasColumnType("float");
|
||||
|
||||
b.Property<DateTime?>("StartSettingDate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<long>("UserId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("SalaryPaymentSetting", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<DateTime>("CreationDate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<string>("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<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Id"));
|
||||
|
||||
b.Property<long?>("AccountId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<DateTime>("CreationDate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.HasMaxLength(150)
|
||||
.HasColumnType("nvarchar(150)");
|
||||
|
||||
b.Property<string>("FullName")
|
||||
.IsRequired()
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("nvarchar(100)");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<string>("Mobile")
|
||||
.IsRequired()
|
||||
.HasMaxLength(20)
|
||||
.HasColumnType("nvarchar(20)");
|
||||
|
||||
b.Property<string>("Password")
|
||||
.IsRequired()
|
||||
.HasMaxLength(1000)
|
||||
.HasColumnType("nvarchar(1000)");
|
||||
|
||||
b.Property<string>("ProfilePhotoPath")
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("nvarchar(500)");
|
||||
|
||||
b.Property<string>("UserName")
|
||||
.IsRequired()
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("nvarchar(100)");
|
||||
|
||||
b.Property<string>("VerifyCode")
|
||||
.HasMaxLength(10)
|
||||
.HasColumnType("nvarchar(10)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Users", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.UserRefreshToken", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<DateTime>("CreationDate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<DateTime>("ExpiresAt")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<string>("IpAddress")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("nvarchar(50)");
|
||||
|
||||
b.Property<DateTime?>("RevokedAt")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<string>("Token")
|
||||
.IsRequired()
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("nvarchar(500)");
|
||||
|
||||
b.Property<string>("UserAgent")
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("nvarchar(500)");
|
||||
|
||||
b.Property<long>("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<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property<long>("Id"));
|
||||
|
||||
b1.Property<int>("Code")
|
||||
.HasColumnType("int");
|
||||
|
||||
b1.Property<long>("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<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property<long>("Id"));
|
||||
|
||||
b1.Property<TimeSpan>("EndShiftOne")
|
||||
.HasColumnType("time(0)");
|
||||
|
||||
b1.Property<TimeSpan>("EndShiftTwo")
|
||||
.HasColumnType("time(0)");
|
||||
|
||||
b1.Property<bool>("HasRestTime")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b1.Property<bool>("HasShiftOne")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b1.Property<bool>("HasShiftTow")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b1.Property<bool>("IsActiveDay")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b1.Property<int>("PersianDayOfWeek")
|
||||
.HasColumnType("int");
|
||||
|
||||
b1.Property<TimeSpan>("RestTime")
|
||||
.HasColumnType("time(0)");
|
||||
|
||||
b1.Property<long>("SalaryPaymentSettingId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b1.Property<int>("ShiftDurationInMinutes")
|
||||
.HasColumnType("int");
|
||||
|
||||
b1.Property<TimeSpan>("StartShiftOne")
|
||||
.HasColumnType("time(0)");
|
||||
|
||||
b1.Property<TimeSpan>("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<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property<long>("Id"));
|
||||
|
||||
b1.Property<long>("RoleId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b1.Property<long>("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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace GozareshgirProgramManager.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class addphasedeploystatusandisarchived : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "DeployStatus",
|
||||
table: "ProjectPhases",
|
||||
type: "nvarchar(30)",
|
||||
maxLength: 30,
|
||||
nullable: false,
|
||||
defaultValue: "");
|
||||
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "IsArchived",
|
||||
table: "ProjectPhases",
|
||||
type: "bit",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "DeployStatus",
|
||||
table: "ProjectPhases");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "IsArchived",
|
||||
table: "ProjectPhases");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<DateTime>("CreationDate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<string>("DeployStatus")
|
||||
.IsRequired()
|
||||
.HasMaxLength(30)
|
||||
.HasColumnType("nvarchar(30)");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasMaxLength(1000)
|
||||
.HasColumnType("nvarchar(1000)");
|
||||
@@ -189,6 +194,9 @@ namespace GozareshgirProgramManager.Infrastructure.Migrations
|
||||
b.Property<bool>("HasAssignmentOverride")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<bool>("IsArchived")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<string>("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 =>
|
||||
|
||||
@@ -48,6 +48,9 @@ public class ProjectPhaseMapping : IEntityTypeConfiguration<ProjectPhase>
|
||||
builder.Property(ph => ph.HasAssignmentOverride)
|
||||
.IsRequired();
|
||||
|
||||
builder.Property(x => x.DeployStatus)
|
||||
.HasConversion<string>().HasMaxLength(30);
|
||||
|
||||
// Relationship with Project
|
||||
builder.HasOne(ph => ph.Project)
|
||||
.WithMany(p => p.Phases)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using GozareshgirProgramManager.Domain.ProjectAgg.Entities;
|
||||
using GozareshgirProgramManager.Domain.ProjectAgg.Enums;
|
||||
using GozareshgirProgramManager.Domain.ProjectAgg.Repositories;
|
||||
using GozareshgirProgramManager.Infrastructure.Persistence._Common;
|
||||
using GozareshgirProgramManager.Infrastructure.Persistence.Context;
|
||||
@@ -35,4 +36,13 @@ public class TaskSectionRepository:RepositoryBase<Guid,TaskSection>,ITaskSection
|
||||
.Where(x => x.CurrentAssignedUserId == userId)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public Task<List<TaskSection>> GetActiveSectionsIncludeAllAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return _context.TaskSections
|
||||
.Where(x => x.Status == TaskSectionStatus.InProgress)
|
||||
.Include(x => x.Activities)
|
||||
.Include(x => x.AdditionalTimes)
|
||||
.ToListAsync(cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -43,9 +43,9 @@ public class RepositoryBase<TKey, T> : IRepository<TKey, T> where T : class
|
||||
return _context.Find<T>(id);
|
||||
}
|
||||
|
||||
public async Task<T?> GetByIdAsync(TKey id)
|
||||
public async Task<T?> GetByIdAsync(TKey id, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return await _context.Set<T>().FindAsync(id);
|
||||
return await _context.Set<T>().FindAsync([id], cancellationToken);
|
||||
}
|
||||
|
||||
public List<T> Get()
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
using System.Runtime.InteropServices;
|
||||
using GozareshgirProgramManager.Application._Common.Models;
|
||||
using GozareshgirProgramManager.Application.Modules.Projects.Commands.AssignProject;
|
||||
using GozareshgirProgramManager.Application.Modules.Projects.Commands.AutoStopOverTimeTaskSections;
|
||||
using GozareshgirProgramManager.Application.Modules.Projects.Commands.AutoUpdateDeployStatus;
|
||||
using GozareshgirProgramManager.Application.Modules.Projects.Commands.ChangeDeployStatusProject;
|
||||
using GozareshgirProgramManager.Application.Modules.Projects.Commands.ChangeStatusSection;
|
||||
using GozareshgirProgramManager.Application.Modules.Projects.Commands.CreateProject;
|
||||
using GozareshgirProgramManager.Application.Modules.Projects.Commands.DeleteProject;
|
||||
@@ -11,6 +14,8 @@ 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.ProjectDeployBoardDetail;
|
||||
using GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectDeployBoardList;
|
||||
using GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectSetTimeDetails;
|
||||
using MediatR;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
@@ -21,70 +26,75 @@ namespace ServiceHost.Areas.Admin.Controllers.ProgramManager;
|
||||
public class ProjectController : ProgramManagerBaseController
|
||||
{
|
||||
private readonly IMediator _mediator;
|
||||
|
||||
|
||||
public ProjectController(IMediator mediator)
|
||||
{
|
||||
_mediator = mediator;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<ActionResult<OperationResult<GetProjectsListResponse>>> Get([FromQuery]GetProjectsListQuery query)
|
||||
public async Task<ActionResult<OperationResult<GetProjectsListResponse>>> Get(
|
||||
[FromQuery] GetProjectsListQuery query)
|
||||
{
|
||||
var res=await _mediator.Send(query);
|
||||
var res = await _mediator.Send(query);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
[HttpPost]
|
||||
public async Task<ActionResult<OperationResult>> Create([FromBody] CreateProjectCommand command)
|
||||
{
|
||||
var res=await _mediator.Send(command);
|
||||
var res = await _mediator.Send(command);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
[HttpPut]
|
||||
public async Task<ActionResult<OperationResult>> Edit([FromBody] EditProjectCommand command)
|
||||
{
|
||||
var res=await _mediator.Send(command);
|
||||
var res = await _mediator.Send(command);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
[HttpDelete]
|
||||
public async Task<ActionResult<OperationResult>> Delete([FromQuery] DeleteProjectCommand command)
|
||||
{
|
||||
var res=await _mediator.Send(command);
|
||||
var res = await _mediator.Send(command);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("assign")]
|
||||
public async Task<ActionResult<OperationResult<GetProjectAssignDetailsResponse>>> GetAssignableProjects(GetProjectAssignDetailsQuery query)
|
||||
public async Task<ActionResult<OperationResult<GetProjectAssignDetailsResponse>>> GetAssignableProjects(
|
||||
GetProjectAssignDetailsQuery query)
|
||||
{
|
||||
var res=await _mediator.Send(query);
|
||||
var res = await _mediator.Send(query);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
[HttpPost("assign")]
|
||||
public async Task<ActionResult<OperationResult>> Assign(AssignProjectCommand command)
|
||||
{
|
||||
var res=await _mediator.Send(command);
|
||||
var res = await _mediator.Send(command);
|
||||
return res;
|
||||
}
|
||||
|
||||
[HttpGet("set-time")]
|
||||
public async Task<ActionResult<OperationResult<ProjectSetTimeResponse>>> GetSetTimeProjectDetails(ProjectSetTimeDetailsQuery query)
|
||||
public async Task<ActionResult<OperationResult<ProjectSetTimeResponse>>> GetSetTimeProjectDetails(
|
||||
ProjectSetTimeDetailsQuery query)
|
||||
{
|
||||
var res=await _mediator.Send(query);
|
||||
var res = await _mediator.Send(query);
|
||||
return res;
|
||||
}
|
||||
|
||||
[HttpPost("set-time")]
|
||||
public async Task<ActionResult<OperationResult>> SetTimeProject(SetTimeProjectCommand command)
|
||||
{
|
||||
var res=await _mediator.Send(command);
|
||||
var res = await _mediator.Send(command);
|
||||
return res;
|
||||
}
|
||||
|
||||
[HttpPost("change-status")]
|
||||
public async Task<ActionResult<OperationResult>> ChangeStatus(ChangeStatusSectionCommand command)
|
||||
{
|
||||
var res = await _mediator.Send(command);
|
||||
var res = await _mediator.Send(command);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -96,11 +106,16 @@ public class ProjectController : ProgramManagerBaseController
|
||||
}
|
||||
|
||||
[HttpGet("board")]
|
||||
public async Task<ActionResult<OperationResult<List<ProjectBoardListResponse>>>> GetProjectBoard([FromQuery] ProjectBoardListQuery query)
|
||||
public async Task<ActionResult<OperationResult<List<ProjectBoardListResponse>>>> GetProjectBoard(
|
||||
[FromQuery] ProjectBoardListQuery query)
|
||||
{
|
||||
// اجرای Command برای متوقف کردن تسکهای overtime قبل از نمایش
|
||||
await _mediator.Send(new AutoStopOverTimeTaskSectionsCommand());
|
||||
|
||||
var res = await _mediator.Send(query);
|
||||
return res;
|
||||
}
|
||||
|
||||
[HttpGet("board/details")]
|
||||
public async Task<ActionResult<OperationResult<ProjectBoardDetailResponse>>> GetProjectBoardDetails(Guid id)
|
||||
{
|
||||
@@ -108,4 +123,28 @@ public class ProjectController : ProgramManagerBaseController
|
||||
var res = await _mediator.Send(query);
|
||||
return res;
|
||||
}
|
||||
|
||||
[HttpGet("deploy-board")]
|
||||
public async Task<ActionResult<OperationResult<GetProjectsDeployBoardListResponse>>> GetProjectDeployBoard()
|
||||
{
|
||||
// قبل از دریافت دیتا، وضعیت دیپلوی را بر اساس تکمیل شدن تمام سکشنها بهروزرسانی میکنیم
|
||||
await _mediator.Send(new AutoUpdateDeployStatusCommand());
|
||||
var request = new GetProjectDeployBoardListQuery();
|
||||
return await _mediator.Send(request);
|
||||
}
|
||||
|
||||
[HttpGet("deploy-board/details")]
|
||||
public async Task<ActionResult<OperationResult<ProjectDeployBoardDetailsResponse>>> GetProjectDeployBoardDetails(Guid id)
|
||||
{
|
||||
var query = new ProjectDeployBoardDetailsQuery(id);
|
||||
var res = await _mediator.Send(query);
|
||||
return res;
|
||||
}
|
||||
|
||||
[HttpPost("deploy-board/change-status")]
|
||||
public async Task<ActionResult<OperationResult>> ChangeDeployStatus(ChangeDeployStatusProjectCommand command)
|
||||
{
|
||||
var res = await _mediator.Send(command);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user