diff --git a/0_Framework/0_Framework.csproj b/0_Framework/0_Framework.csproj index 54b62986..ad747dc2 100644 --- a/0_Framework/0_Framework.csproj +++ b/0_Framework/0_Framework.csproj @@ -1,21 +1,25 @@  - net8.0 + net10.0 _0_Framework - - - - - - + + + + + + + + + - - - + + + + diff --git a/0_Framework/Application/AuthHelper.cs b/0_Framework/Application/AuthHelper.cs index ef510830..12f820f8 100644 --- a/0_Framework/Application/AuthHelper.cs +++ b/0_Framework/Application/AuthHelper.cs @@ -198,7 +198,8 @@ public class AuthHelper : IAuthHelper new("workshopList",workshopBson), new("WorkshopSlug",slug), new("WorkshopId", account.WorkshopId.ToString()), - new("WorkshopName",account.WorkshopName??"") + new("WorkshopName",account.WorkshopName??""), + new("pm.userId", account.PmUserId?.ToString() ?? "0"), }; diff --git a/0_Framework/Application/AuthViewModel.cs b/0_Framework/Application/AuthViewModel.cs index d419bd67..aebda696 100644 --- a/0_Framework/Application/AuthViewModel.cs +++ b/0_Framework/Application/AuthViewModel.cs @@ -27,10 +27,12 @@ public class AuthViewModel #endregion public long SubAccountId { get; set; } + public long? PmUserId { get; set; } public AuthViewModel(long id, long roleId, string fullname, string username, string mobile,string profilePhoto, - List permissions, string roleName, string adminAreaPermission, string clientAriaPermission, int? positionValue, long subAccountId = 0) + List permissions, string roleName, string adminAreaPermission, string clientAriaPermission, int? positionValue, + long subAccountId = 0,long? pmUserId = null) { Id = id; RoleId = roleId; @@ -44,6 +46,7 @@ public class AuthViewModel ClientAriaPermission = clientAriaPermission; PositionValue = positionValue; SubAccountId = subAccountId; + PmUserId = pmUserId; } public AuthViewModel() diff --git a/AccountManagement.Application.Contracts/AccountManagement.Application.Contracts.csproj b/AccountManagement.Application.Contracts/AccountManagement.Application.Contracts.csproj index 36069642..57db0cd1 100644 --- a/AccountManagement.Application.Contracts/AccountManagement.Application.Contracts.csproj +++ b/AccountManagement.Application.Contracts/AccountManagement.Application.Contracts.csproj @@ -1,15 +1,20 @@ - net8.0 + net10.0 - + + + + + + diff --git a/AccountManagement.Application.Contracts/Role/IRoleApplication.cs b/AccountManagement.Application.Contracts/Role/IRoleApplication.cs index 9d49f8e2..68f3ab52 100644 --- a/AccountManagement.Application.Contracts/Role/IRoleApplication.cs +++ b/AccountManagement.Application.Contracts/Role/IRoleApplication.cs @@ -1,8 +1,9 @@ using _0_Framework.Application; -using AccountManagement.Application.Contracts.ProgramManager; + using Microsoft.AspNetCore.Mvc.Rendering; using System.Collections.Generic; using System.Threading.Tasks; +using Shared.Contracts.PmRole.Queries; namespace AccountManagement.Application.Contracts.Role { diff --git a/AccountManagement.Application/AccountApplication.cs b/AccountManagement.Application/AccountApplication.cs index bba09128..8676a795 100644 --- a/AccountManagement.Application/AccountApplication.cs +++ b/AccountManagement.Application/AccountApplication.cs @@ -34,6 +34,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using AccountManagement.Application.Contracts.ProgramManager; +using Shared.Contracts.PmUser; using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database; //using AccountManagement.Domain.RoleAgg; @@ -58,9 +59,10 @@ public class AccountApplication : IAccountApplication private readonly ISubAccountPermissionSubtitle1Repository _accountPermissionSubtitle1Repository; private readonly IPmUserRepository _pmUserRepository; private readonly IUnitOfWork _unitOfWork; + private readonly IPmUserQueryService _pmUserQueryService; public AccountApplication(IAccountRepository accountRepository, IPasswordHasher passwordHasher, - IFileUploader fileUploader, IAuthHelper authHelper, IRoleRepository roleRepository, IWorker worker, ISmsService smsService, ICameraAccountRepository cameraAccountRepository, IPositionRepository positionRepository, IAccountLeftworkRepository accountLeftworkRepository, IWorkshopRepository workshopRepository, ISubAccountRepository subAccountRepository, ISubAccountRoleRepository subAccountRoleRepository, IWorkshopSubAccountRepository workshopSubAccountRepository, ISubAccountPermissionSubtitle1Repository accountPermissionSubtitle1Repository, IUnitOfWork unitOfWork, IPmUserRepository pmUserRepository) + IFileUploader fileUploader, IAuthHelper authHelper, IRoleRepository roleRepository, IWorker worker, ISmsService smsService, ICameraAccountRepository cameraAccountRepository, IPositionRepository positionRepository, IAccountLeftworkRepository accountLeftworkRepository, IWorkshopRepository workshopRepository, ISubAccountRepository subAccountRepository, ISubAccountRoleRepository subAccountRoleRepository, IWorkshopSubAccountRepository workshopSubAccountRepository, ISubAccountPermissionSubtitle1Repository accountPermissionSubtitle1Repository, IUnitOfWork unitOfWork, IPmUserRepository pmUserRepository, IPmUserQueryService pmUserQueryService) { _authHelper = authHelper; _roleRepository = roleRepository; @@ -75,6 +77,7 @@ public class AccountApplication : IAccountApplication _accountPermissionSubtitle1Repository = accountPermissionSubtitle1Repository; _unitOfWork = unitOfWork; _pmUserRepository = pmUserRepository; + _pmUserQueryService = pmUserQueryService; _fileUploader = fileUploader; _passwordHasher = passwordHasher; _accountRepository = accountRepository; @@ -463,8 +466,11 @@ public class AccountApplication : IAccountApplication { positionValue = null; } + var pmUserId = _pmUserQueryService.GetCurrentPmUserIdFromAccountId(account.id).GetAwaiter().GetResult(); var authViewModel = new AuthViewModel(account.id, account.RoleId, account.Fullname - , account.Username, account.Mobile, account.ProfilePhoto, permissions, account.RoleName, account.AdminAreaPermission, account.ClientAriaPermission, positionValue); + , account.Username, account.Mobile, account.ProfilePhoto, + permissions, account.RoleName, account.AdminAreaPermission, + account.ClientAriaPermission, positionValue,0,pmUserId); if (account.ClientAriaPermission == "true" && account.AdminAreaPermission == "false" && account.IsActiveString == "true") diff --git a/AccountManagement.Application/AccountManagement.Application.csproj b/AccountManagement.Application/AccountManagement.Application.csproj index 7fcb4ebe..15c192f3 100644 --- a/AccountManagement.Application/AccountManagement.Application.csproj +++ b/AccountManagement.Application/AccountManagement.Application.csproj @@ -1,13 +1,14 @@  - net8.0 + net10.0 + diff --git a/AccountManagement.Application/RoleApplication.cs b/AccountManagement.Application/RoleApplication.cs index 6ea605d4..02d027c0 100644 --- a/AccountManagement.Application/RoleApplication.cs +++ b/AccountManagement.Application/RoleApplication.cs @@ -4,7 +4,6 @@ using AccountManagement.Domain.RoleAgg; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using AccountManagement.Application.Contracts.ProgramManager; using AccountManagement.Application.Contracts.ProgramManagerApiResult; using AccountManagement.Domain.InternalApiCaller; using Company.Domain._common; @@ -13,7 +12,10 @@ using AccountManagement.Domain.PmDomains.PmPermissionAgg; using AccountManagement.Domain.PmDomains.PmRoleAgg; using AccountManagement.Domain.PmDomains.PmUserAgg; using Microsoft.AspNetCore.Mvc.Rendering; +using Shared.Contracts.PmRole.Commands; +using GetPmRolesDto = Shared.Contracts.PmRole.Queries.GetPmRolesDto; using Role = AccountManagement.Domain.RoleAgg.Role; +using Shared.Contracts.PmRole.Queries; namespace AccountManagement.Application; @@ -22,14 +24,18 @@ public class RoleApplication : IRoleApplication private readonly IRoleRepository _roleRepository; private readonly IPmRoleRepository _pmRoleRepository; private readonly IPmUserRepository _pmUserRepository; + private readonly IPmRoleQueryService _pmRoleQueryService; + private readonly IPmRoleCommandService _pmRoleCommandService; private readonly IUnitOfWork _unitOfWork; - public RoleApplication(IRoleRepository roleRepository, IUnitOfWork unitOfWork, IPmRoleRepository pmRoleRepository, IPmUserRepository pmUserRepository) + public RoleApplication(IRoleRepository roleRepository, IUnitOfWork unitOfWork, IPmRoleRepository pmRoleRepository, IPmUserRepository pmUserRepository, IPmRoleQueryService pmRoleQueryService, IPmRoleCommandService pmRoleCommandService) { _roleRepository = roleRepository; _unitOfWork = unitOfWork; _pmRoleRepository = pmRoleRepository; _pmUserRepository = pmUserRepository; + _pmRoleQueryService = pmRoleQueryService; + _pmRoleCommandService = pmRoleCommandService; } public async Task Create(CreateRole command) @@ -47,19 +53,15 @@ public class RoleApplication : IRoleApplication var pmPermissions = command.PmPermissions.Where(x => x > 0).ToList(); if (pmPermissions.Any()) { - try - { - var pmPermissionsData = pmPermissions.Where(x => x > 0).Select(x => new PmPermission(x)).ToList(); - var pmRole = new PmRole(command.Name, role.id, pmPermissionsData); - await _pmRoleRepository.CreateAsync(pmRole); - await _pmRoleRepository.SaveChangesAsync(); - - } - catch (System.Exception) + + var pmRole = new CreatePmRoleDto{ RoleName = command.Name, Permissions = pmPermissions, GozareshgirRoleId = role.id}; + var res =await _pmRoleCommandService.Create(pmRole); + if (!res.Item1) { _unitOfWork.RollbackAccountContext(); return operation.Failed("خطا در ویرایش دسترسی ها در پروگرام منیجر"); } + //var parameters = new CreateProgramManagerRole //{ @@ -136,24 +138,20 @@ public class RoleApplication : IRoleApplication //); - var pmRoleResult = await _pmRoleRepository.GetPmRoleToEdit(command.Id); - + var pmRoleListResult = await _pmRoleQueryService.GetPmRoleList(command.Id); + var pmRoleResult = pmRoleListResult.FirstOrDefault(); //اگر این نقش در پروگرام منیجر وجود داشت ویرایش کن if (pmRoleResult != null) { - - try - { - var pmpermissionsData = pmPermissions.Where(x => x > 0).Select(x => new PmPermission(x)).ToList(); - pmRoleResult.Edit(command.Name, pmpermissionsData); - await _pmRoleRepository.SaveChangesAsync(); - } - catch (System.Exception) + var edit = new CreatePmRoleDto { RoleName = command.Name, Permissions = pmPermissions, GozareshgirRoleId = role.id }; + var res = await _pmRoleCommandService.Edit(edit); + if (!res.Item1) { _unitOfWork.RollbackAccountContext(); return operation.Failed("خطا در ویرایش دسترسی ها در پروگرام منیجر"); } + //var parameters = new CreateProgramManagerRole @@ -254,7 +252,7 @@ public class RoleApplication : IRoleApplication public async Task GetPmRoleList(long? gozareshgirRoleId) { - var rolse = await _pmRoleRepository.GetPmRoleList(gozareshgirRoleId); + var rolse = await _pmRoleQueryService.GetPmRoleList(gozareshgirRoleId); return new SelectList(rolse, "Id", "RoleName"); @@ -262,7 +260,7 @@ public class RoleApplication : IRoleApplication public async Task> GetPmRoleListToEdit(long? gozareshgirRoleId) { - return await _pmRoleRepository.GetPmRoleList(gozareshgirRoleId); + return await _pmRoleQueryService.GetPmRoleList(gozareshgirRoleId); } diff --git a/AccountManagement.Configuration/AccountManagement.Configuration.csproj b/AccountManagement.Configuration/AccountManagement.Configuration.csproj index 0b172228..1500e750 100644 --- a/AccountManagement.Configuration/AccountManagement.Configuration.csproj +++ b/AccountManagement.Configuration/AccountManagement.Configuration.csproj @@ -1,13 +1,13 @@ - net8.0 + net10.0 - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/AccountManagement.Domain/AccountManagement.Domain.csproj b/AccountManagement.Domain/AccountManagement.Domain.csproj index 031bd6e0..bcefc806 100644 --- a/AccountManagement.Domain/AccountManagement.Domain.csproj +++ b/AccountManagement.Domain/AccountManagement.Domain.csproj @@ -1,9 +1,16 @@ - net8.0 + net10.0 + + + + + + + diff --git a/AccountMangement.Infrastructure.EFCore/AccountMangement.Infrastructure.EFCore.csproj b/AccountMangement.Infrastructure.EFCore/AccountMangement.Infrastructure.EFCore.csproj index 8f6a5df5..3517ef07 100644 --- a/AccountMangement.Infrastructure.EFCore/AccountMangement.Infrastructure.EFCore.csproj +++ b/AccountMangement.Infrastructure.EFCore/AccountMangement.Infrastructure.EFCore.csproj @@ -1,13 +1,15 @@  - net8.0 + net10.0 - - - + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -18,6 +20,10 @@ + + + + diff --git a/AccountMangement.Infrastructure.EFCore/Migrations/20251213112030_add programmanger boo in account.Designer.cs b/AccountMangement.Infrastructure.EFCore/Migrations/20251213112030_add programmanger boo in account.Designer.cs new file mode 100644 index 00000000..4b9d6614 --- /dev/null +++ b/AccountMangement.Infrastructure.EFCore/Migrations/20251213112030_add programmanger boo in account.Designer.cs @@ -0,0 +1,1452 @@ +// +using System; +using AccountMangement.Infrastructure.EFCore; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace AccountMangement.Infrastructure.EFCore.Migrations +{ + [DbContext(typeof(AccountContext))] + [Migration("20251213112030_add programmanger boo in account")] + partial class addprogrammangerbooinaccount + { + /// + 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("AccountManagement.Domain.AccountAgg.Account", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("AdminAreaPermission") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.Property("ClientAriaPermission") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .HasMaxLength(150) + .HasColumnType("nvarchar(150)"); + + b.Property("Fullname") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("IsActiveString") + .HasMaxLength(6) + .HasColumnType("nvarchar(6)"); + + b.Property("IsProgramManagerUser") + .HasColumnType("bit"); + + b.Property("Mobile") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.Property("NationalCode") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.Property("Password") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("PositionId") + .HasMaxLength(10) + .HasColumnType("bigint"); + + b.Property("PositionIsActive") + .HasMaxLength(5) + .HasColumnType("nvarchar(5)"); + + b.Property("ProfilePhoto") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("RoleId") + .HasColumnType("bigint"); + + b.Property("RoleName") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("Username") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("VerifyCode") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.HasKey("id"); + + b.HasIndex("PositionId"); + + b.HasIndex("RoleId"); + + b.ToTable("Accounts", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.AccountLeftWorkAgg.AccountLeftWork", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("LeftWorkGr") + .HasColumnType("datetime2"); + + b.Property("RoleId") + .HasColumnType("bigint"); + + b.Property("StartWorkGr") + .HasColumnType("datetime2"); + + b.Property("WorkshopId") + .HasColumnType("bigint"); + + b.HasKey("id"); + + b.HasIndex("AccountId"); + + b.ToTable("AccountLeftWork", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.AdminResponseAgg.AdminResponse", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("AdminAccountId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("IsActiveString") + .HasMaxLength(5) + .HasColumnType("nvarchar(5)"); + + b.Property("Response") + .HasColumnType("ntext"); + + b.Property("TicketId") + .HasColumnType("bigint"); + + b.HasKey("id"); + + b.HasIndex("TicketId"); + + b.ToTable("AdminResponses", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.AdminResponseMediaAgg.AdminResponseMedia", b => + { + b.Property("AdminResponseId") + .HasColumnType("bigint"); + + b.Property("MediaId") + .HasColumnType("bigint"); + + b.HasKey("AdminResponseId", "MediaId"); + + b.HasIndex("MediaId"); + + b.ToTable("AdminResponseMedias", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.AssignAgg.Assign", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("AcceptedTimeRequest") + .HasColumnType("int"); + + b.Property("AssignedId") + .HasColumnType("bigint"); + + b.Property("AssignedName") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("AssignedPositionValue") + .HasColumnType("int"); + + b.Property("AssignerId") + .HasColumnType("bigint"); + + b.Property("AssignerPositionValue") + .HasColumnType("int"); + + b.Property("CancelDescription") + .HasColumnType("ntext"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("DoneDescription") + .HasColumnType("ntext"); + + b.Property("EndTaskDate") + .HasColumnType("datetime2"); + + b.Property("FirstTimeCreation") + .HasColumnType("bit"); + + b.Property("IsCancel") + .HasColumnType("bit"); + + b.Property("IsCanceledRequest") + .HasColumnType("bit"); + + b.Property("IsDone") + .HasColumnType("bit"); + + b.Property("IsDoneRequest") + .HasColumnType("bit"); + + b.Property("RequestDate") + .HasColumnType("datetime2"); + + b.Property("TaskId") + .HasColumnType("bigint"); + + b.Property("TimeRequest") + .HasColumnType("bit"); + + b.Property("TimeRequestDescription") + .HasColumnType("ntext"); + + b.HasKey("id"); + + b.HasIndex("TaskId"); + + b.ToTable("Assigns", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.CameraAccountAgg.CameraAccount", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("IsActiveSting") + .IsRequired() + .HasMaxLength(5) + .HasColumnType("nvarchar(5)"); + + b.Property("Mobile") + .HasMaxLength(11) + .HasColumnType("nvarchar(11)"); + + b.Property("Password") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("Username") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("WorkshopId") + .HasColumnType("bigint"); + + b.Property("WorkshopName") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.HasKey("id"); + + b.HasIndex("AccountId"); + + b.ToTable("CameraAccounts", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.ClientResponseAgg.ClientResponse", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Response") + .HasColumnType("ntext"); + + b.Property("TicketId") + .HasColumnType("bigint"); + + b.HasKey("id"); + + b.HasIndex("TicketId"); + + b.ToTable("ClientResponses", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.ClientResponseMediaAgg.ClientResponseMedia", b => + { + b.Property("ClientResponseId") + .HasColumnType("bigint"); + + b.Property("MediaId") + .HasColumnType("bigint"); + + b.HasKey("ClientResponseId", "MediaId"); + + b.HasIndex("MediaId"); + + b.ToTable("ClientResponseMedias", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.MediaAgg.Media", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("Category") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Path") + .HasColumnType("ntext"); + + b.Property("ServiceName") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Type") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.HasKey("id"); + + b.ToTable("Medias", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.PmDomains.PmRoleAgg.PmRole", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("GozareshgirRoleId") + .HasColumnType("bigint"); + + b.Property("RoleName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.HasKey("id"); + + b.ToTable("PmRoles", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("AccountManagement.Domain.PmDomains.PmUserAgg.PmUser", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .HasMaxLength(150) + .HasColumnType("nvarchar(150)"); + + b.Property("FullName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("Mobile") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.Property("Password") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("ProfilePhotoPath") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("VerifyCode") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.HasKey("id"); + + b.ToTable("Users", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.PositionAgg.Position", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("PositionName") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("PositionValue") + .HasMaxLength(2) + .HasColumnType("int"); + + b.HasKey("id"); + + b.ToTable("Positions", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.RoleAgg.Role", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.HasKey("id"); + + b.ToTable("Roles", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.SubAccountAgg.SubAccount", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("FName") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("IsActive") + .IsRequired() + .HasMaxLength(5) + .HasColumnType("nvarchar(5)"); + + b.Property("LName") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("NationalCode") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.Property("Password") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("PhoneNumber") + .IsRequired() + .HasMaxLength(11) + .HasColumnType("nvarchar(11)"); + + b.Property("ProfilePhoto") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("SubAccountRoleId") + .HasColumnType("bigint"); + + b.Property("Username") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("VerifyCode") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.HasKey("id"); + + b.HasIndex("SubAccountRoleId"); + + b.ToTable("SubAccounts", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.SubAccountPermissionSubtitle1Agg.SubAccountPermissionSubtitle1", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("Code") + .HasMaxLength(15) + .HasColumnType("int"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("id"); + + b.ToTable("SubAccountPermissionSubtitle1", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.SubAccountPermissionSubtitle2Agg.SubAccountPermissionSubtitle2", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("Code") + .HasMaxLength(15) + .HasColumnType("int"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("ParentId") + .HasColumnType("bigint"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("id"); + + b.HasIndex("ParentId"); + + b.ToTable("SubAccountPermissionSubtitle2", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.SubAccountPermissionSubtitle3Agg.SubAccountPermissionSubtitle3", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("Code") + .HasMaxLength(15) + .HasColumnType("int"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("ParentId") + .HasColumnType("bigint"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("id"); + + b.HasIndex("ParentId"); + + b.ToTable("SubAccountPermissionSubtitle3", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.SubAccountPermissionSubtitle4Agg.SubAccountPermissionSubtitle4", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("Code") + .HasMaxLength(15) + .HasColumnType("int"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("ParentId") + .HasColumnType("bigint"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("id"); + + b.HasIndex("ParentId"); + + b.ToTable("SubAccountPermissionSubtitle4", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.SubAccountRoleAgg.SubAccountRole", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Title") + .HasMaxLength(60) + .HasColumnType("nvarchar(60)"); + + b.HasKey("id"); + + b.ToTable("SubAccountRoles", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.TaskAgg.Tasks", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("ContractingPartyName") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasColumnType("ntext"); + + b.Property("IsActiveString") + .HasMaxLength(7) + .HasColumnType("nvarchar(7)"); + + b.Property("SenderId") + .HasColumnType("bigint"); + + b.Property("StartTaskDate") + .HasColumnType("datetime2"); + + b.Property("TaskScheduleId") + .HasColumnType("bigint"); + + b.Property("TicketId") + .HasColumnType("bigint"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.HasKey("id"); + + b.HasIndex("TaskScheduleId"); + + b.ToTable("TasksManager", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.TaskMediaAgg.TaskMedia", b => + { + b.Property("MediaId") + .HasColumnType("bigint"); + + b.Property("TaskId") + .HasColumnType("bigint"); + + b.HasKey("MediaId", "TaskId"); + + b.HasIndex("TaskId"); + + b.ToTable("TasksMedias", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.TaskMessageAgg.TaskMessage", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("AssignId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Message") + .HasColumnType("ntext"); + + b.Property("RequestedDateFa") + .HasMaxLength(25) + .HasColumnType("nvarchar(25)"); + + b.Property("TypeOfMessage") + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.HasKey("id"); + + b.HasIndex("AssignId"); + + b.ToTable("TaskMessages", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.TaskMessageItemsAgg.TaskMessageItems", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("ReceiverAccountId") + .HasColumnType("bigint"); + + b.Property("SenderAccountId") + .HasColumnType("bigint"); + + b.Property("TaskMessageId") + .HasColumnType("bigint"); + + b.HasKey("id"); + + b.HasIndex("TaskMessageId"); + + b.ToTable("TaskMessageItems", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.TaskScheduleAgg.TaskSchedule", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("Count") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("IsActive") + .IsRequired() + .HasMaxLength(5) + .HasColumnType("nvarchar(5)"); + + b.Property("LastEndTaskDate") + .HasColumnType("datetime2"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(12) + .HasColumnType("nvarchar(12)"); + + b.Property("UnitNumber") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.Property("UnitType") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.HasKey("id"); + + b.ToTable("TaskSchedules", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.TaskSubjectAgg.TaskSubject", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Subject") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.HasKey("id"); + + b.ToTable("TaskSubjects", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.TicketAccessAccountAgg.TicketAccessAccount", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.HasKey("id"); + + b.ToTable("TicketAccessAccounts", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.TicketAgg.Ticket", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("ContractingPartyName") + .HasMaxLength(155) + .HasColumnType("nvarchar(155)"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasColumnType("ntext"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("SenderId") + .HasColumnType("bigint"); + + b.Property("Status") + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("SubAccountSenderId") + .HasColumnType("bigint"); + + b.Property("TicketNumber") + .HasMaxLength(12) + .HasColumnType("nvarchar(12)"); + + b.Property("TicketType") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Title") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("WorkshopId") + .HasColumnType("bigint"); + + b.HasKey("id"); + + b.ToTable("Tickets", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.TicketMediasAgg.TicketMedia", b => + { + b.Property("TicketId") + .HasColumnType("bigint"); + + b.Property("MediaId") + .HasColumnType("bigint"); + + b.HasKey("TicketId", "MediaId"); + + b.HasIndex("MediaId"); + + b.ToTable("TicketMedias", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.AccountAgg.Account", b => + { + b.HasOne("AccountManagement.Domain.PositionAgg.Position", "Position") + .WithMany("Accounts") + .HasForeignKey("PositionId"); + + b.HasOne("AccountManagement.Domain.RoleAgg.Role", "Role") + .WithMany("Accounts") + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Position"); + + b.Navigation("Role"); + }); + + modelBuilder.Entity("AccountManagement.Domain.AccountLeftWorkAgg.AccountLeftWork", b => + { + b.HasOne("AccountManagement.Domain.AccountAgg.Account", "Account") + .WithMany("AccountLeftWorkList") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("AccountManagement.Domain.AdminResponseAgg.AdminResponse", b => + { + b.HasOne("AccountManagement.Domain.TicketAgg.Ticket", "Ticket") + .WithMany("AdminResponses") + .HasForeignKey("TicketId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Ticket"); + }); + + modelBuilder.Entity("AccountManagement.Domain.AdminResponseMediaAgg.AdminResponseMedia", b => + { + b.HasOne("AccountManagement.Domain.AdminResponseAgg.AdminResponse", "AdminResponse") + .WithMany("AdminResponseMedias") + .HasForeignKey("AdminResponseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AccountManagement.Domain.MediaAgg.Media", "Media") + .WithMany("AdminResponseMedias") + .HasForeignKey("MediaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("AdminResponse"); + + b.Navigation("Media"); + }); + + modelBuilder.Entity("AccountManagement.Domain.AssignAgg.Assign", b => + { + b.HasOne("AccountManagement.Domain.TaskAgg.Tasks", "Task") + .WithMany("Assigns") + .HasForeignKey("TaskId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("AccountManagement.Domain.CameraAccountAgg.CameraAccount", b => + { + b.HasOne("AccountManagement.Domain.AccountAgg.Account", "Account") + .WithMany("CameraAccounts") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("AccountManagement.Domain.ClientResponseAgg.ClientResponse", b => + { + b.HasOne("AccountManagement.Domain.TicketAgg.Ticket", "Ticket") + .WithMany("ClientResponses") + .HasForeignKey("TicketId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Ticket"); + }); + + modelBuilder.Entity("AccountManagement.Domain.ClientResponseMediaAgg.ClientResponseMedia", b => + { + b.HasOne("AccountManagement.Domain.ClientResponseAgg.ClientResponse", "ClientResponse") + .WithMany("ClientResponseMedias") + .HasForeignKey("ClientResponseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AccountManagement.Domain.MediaAgg.Media", "Media") + .WithMany("ClientResponseMedias") + .HasForeignKey("MediaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ClientResponse"); + + b.Navigation("Media"); + }); + + modelBuilder.Entity("AccountManagement.Domain.PmDomains.PmRoleAgg.PmRole", b => + { + b.OwnsMany("AccountManagement.Domain.PmDomains.PmPermissionAgg.PmPermission", "PmPermission", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("Code") + .HasColumnType("int"); + + b1.Property("Roleid") + .HasColumnType("bigint"); + + b1.HasKey("Id"); + + b1.HasIndex("Roleid"); + + b1.ToTable("PmRolePermissions", null, t => + { + t.ExcludeFromMigrations(); + }); + + b1.WithOwner("Role") + .HasForeignKey("Roleid"); + + b1.Navigation("Role"); + }); + + b.Navigation("PmPermission"); + }); + + modelBuilder.Entity("AccountManagement.Domain.PmDomains.PmUserAgg.PmUser", b => + { + b.OwnsMany("AccountManagement.Domain.PmDomains.PmRoleUserAgg.PmRoleUser", "RoleUser", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("RoleId") + .HasColumnType("bigint"); + + b1.Property("Userid") + .HasColumnType("bigint"); + + b1.HasKey("Id"); + + b1.HasIndex("Userid"); + + b1.ToTable("RoleUsers", (string)null); + + b1.WithOwner("User") + .HasForeignKey("Userid"); + + b1.Navigation("User"); + }); + + b.Navigation("RoleUser"); + }); + + modelBuilder.Entity("AccountManagement.Domain.RoleAgg.Role", b => + { + b.OwnsMany("AccountManagement.Domain.RoleAgg.Permission", "Permissions", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("Code") + .HasColumnType("int"); + + b1.Property("RoleId") + .HasColumnType("bigint"); + + b1.HasKey("Id"); + + b1.HasIndex("RoleId"); + + b1.ToTable("RolePermissions", (string)null); + + b1.WithOwner("Role") + .HasForeignKey("RoleId"); + + b1.Navigation("Role"); + }); + + b.Navigation("Permissions"); + }); + + modelBuilder.Entity("AccountManagement.Domain.SubAccountAgg.SubAccount", b => + { + b.HasOne("AccountManagement.Domain.SubAccountRoleAgg.SubAccountRole", "SubAccountRole") + .WithMany("SubAccounts") + .HasForeignKey("SubAccountRoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("SubAccountRole"); + }); + + modelBuilder.Entity("AccountManagement.Domain.SubAccountPermissionSubtitle2Agg.SubAccountPermissionSubtitle2", b => + { + b.HasOne("AccountManagement.Domain.SubAccountPermissionSubtitle1Agg.SubAccountPermissionSubtitle1", "Parent") + .WithMany("Children") + .HasForeignKey("ParentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Parent"); + }); + + modelBuilder.Entity("AccountManagement.Domain.SubAccountPermissionSubtitle3Agg.SubAccountPermissionSubtitle3", b => + { + b.HasOne("AccountManagement.Domain.SubAccountPermissionSubtitle2Agg.SubAccountPermissionSubtitle2", "Parent") + .WithMany("Children") + .HasForeignKey("ParentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Parent"); + }); + + modelBuilder.Entity("AccountManagement.Domain.SubAccountPermissionSubtitle4Agg.SubAccountPermissionSubtitle4", b => + { + b.HasOne("AccountManagement.Domain.SubAccountPermissionSubtitle3Agg.SubAccountPermissionSubtitle3", "Parent") + .WithMany("Children") + .HasForeignKey("ParentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Parent"); + }); + + modelBuilder.Entity("AccountManagement.Domain.SubAccountRoleAgg.SubAccountRole", b => + { + b.OwnsMany("AccountManagement.Domain.SubAccountRoleAgg.SubAccountRoleWorkshop", "RoleWorkshops", b1 => + { + b1.Property("SubAccountId") + .HasColumnType("bigint"); + + b1.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("id")); + + b1.Property("CreationDate") + .HasColumnType("datetime2"); + + b1.Property("WorkshopId") + .HasColumnType("bigint"); + + b1.HasKey("SubAccountId", "id"); + + b1.ToTable("SubAccountRoleWorkshop"); + + b1.WithOwner("SubAccountRole") + .HasForeignKey("SubAccountId"); + + b1.Navigation("SubAccountRole"); + }); + + b.OwnsMany("AccountManagement.Domain.SubAccountRoleAgg.SubAccountRolePermission", "RolePermissions", b1 => + { + b1.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("id")); + + b1.Property("PermissionCode") + .HasColumnType("int"); + + b1.Property("SubAccountRoleId") + .HasColumnType("bigint"); + + b1.HasKey("id"); + + b1.HasIndex("SubAccountRoleId"); + + b1.ToTable("SubAccountRolePermissions", (string)null); + + b1.WithOwner("SubAccountRole") + .HasForeignKey("SubAccountRoleId"); + + b1.Navigation("SubAccountRole"); + }); + + b.Navigation("RolePermissions"); + + b.Navigation("RoleWorkshops"); + }); + + modelBuilder.Entity("AccountManagement.Domain.TaskAgg.Tasks", b => + { + b.HasOne("AccountManagement.Domain.TaskScheduleAgg.TaskSchedule", "TaskSchedule") + .WithMany("TasksList") + .HasForeignKey("TaskScheduleId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("TaskSchedule"); + }); + + modelBuilder.Entity("AccountManagement.Domain.TaskMediaAgg.TaskMedia", b => + { + b.HasOne("AccountManagement.Domain.MediaAgg.Media", "Media") + .WithMany("TaskMedias") + .HasForeignKey("MediaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AccountManagement.Domain.TaskAgg.Tasks", "Tasks") + .WithMany("TaskMedias") + .HasForeignKey("TaskId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Media"); + + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("AccountManagement.Domain.TaskMessageAgg.TaskMessage", b => + { + b.HasOne("AccountManagement.Domain.AssignAgg.Assign", "Assign") + .WithMany("TaskMessageList") + .HasForeignKey("AssignId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Assign"); + }); + + modelBuilder.Entity("AccountManagement.Domain.TaskMessageItemsAgg.TaskMessageItems", b => + { + b.HasOne("AccountManagement.Domain.TaskMessageAgg.TaskMessage", "TaskMessage") + .WithMany("TaskMessageItemsList") + .HasForeignKey("TaskMessageId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("TaskMessage"); + }); + + modelBuilder.Entity("AccountManagement.Domain.TicketMediasAgg.TicketMedia", b => + { + b.HasOne("AccountManagement.Domain.MediaAgg.Media", "Media") + .WithMany("TicketMedias") + .HasForeignKey("MediaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AccountManagement.Domain.TicketAgg.Ticket", "Ticket") + .WithMany("TicketMedias") + .HasForeignKey("TicketId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Media"); + + b.Navigation("Ticket"); + }); + + modelBuilder.Entity("AccountManagement.Domain.AccountAgg.Account", b => + { + b.Navigation("AccountLeftWorkList"); + + b.Navigation("CameraAccounts"); + }); + + modelBuilder.Entity("AccountManagement.Domain.AdminResponseAgg.AdminResponse", b => + { + b.Navigation("AdminResponseMedias"); + }); + + modelBuilder.Entity("AccountManagement.Domain.AssignAgg.Assign", b => + { + b.Navigation("TaskMessageList"); + }); + + modelBuilder.Entity("AccountManagement.Domain.ClientResponseAgg.ClientResponse", b => + { + b.Navigation("ClientResponseMedias"); + }); + + modelBuilder.Entity("AccountManagement.Domain.MediaAgg.Media", b => + { + b.Navigation("AdminResponseMedias"); + + b.Navigation("ClientResponseMedias"); + + b.Navigation("TaskMedias"); + + b.Navigation("TicketMedias"); + }); + + modelBuilder.Entity("AccountManagement.Domain.PositionAgg.Position", b => + { + b.Navigation("Accounts"); + }); + + modelBuilder.Entity("AccountManagement.Domain.RoleAgg.Role", b => + { + b.Navigation("Accounts"); + }); + + modelBuilder.Entity("AccountManagement.Domain.SubAccountPermissionSubtitle1Agg.SubAccountPermissionSubtitle1", b => + { + b.Navigation("Children"); + }); + + modelBuilder.Entity("AccountManagement.Domain.SubAccountPermissionSubtitle2Agg.SubAccountPermissionSubtitle2", b => + { + b.Navigation("Children"); + }); + + modelBuilder.Entity("AccountManagement.Domain.SubAccountPermissionSubtitle3Agg.SubAccountPermissionSubtitle3", b => + { + b.Navigation("Children"); + }); + + modelBuilder.Entity("AccountManagement.Domain.SubAccountRoleAgg.SubAccountRole", b => + { + b.Navigation("SubAccounts"); + }); + + modelBuilder.Entity("AccountManagement.Domain.TaskAgg.Tasks", b => + { + b.Navigation("Assigns"); + + b.Navigation("TaskMedias"); + }); + + modelBuilder.Entity("AccountManagement.Domain.TaskMessageAgg.TaskMessage", b => + { + b.Navigation("TaskMessageItemsList"); + }); + + modelBuilder.Entity("AccountManagement.Domain.TaskScheduleAgg.TaskSchedule", b => + { + b.Navigation("TasksList"); + }); + + modelBuilder.Entity("AccountManagement.Domain.TicketAgg.Ticket", b => + { + b.Navigation("AdminResponses"); + + b.Navigation("ClientResponses"); + + b.Navigation("TicketMedias"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/AccountMangement.Infrastructure.EFCore/Migrations/20251213112030_add programmanger boo in account.cs b/AccountMangement.Infrastructure.EFCore/Migrations/20251213112030_add programmanger boo in account.cs new file mode 100644 index 00000000..0c315d34 --- /dev/null +++ b/AccountMangement.Infrastructure.EFCore/Migrations/20251213112030_add programmanger boo in account.cs @@ -0,0 +1,31 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace AccountMangement.Infrastructure.EFCore.Migrations +{ + /// + public partial class addprogrammangerbooinaccount : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "IsProgramManagerUser", + table: "Accounts", + type: "bit", + nullable: false, + defaultValue: false); + + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "IsProgramManagerUser", + table: "Accounts"); + } + } +} diff --git a/AccountMangement.Infrastructure.EFCore/Migrations/20251213143102_romoveIsProgramManagerUserFromAccount.Designer.cs b/AccountMangement.Infrastructure.EFCore/Migrations/20251213143102_romoveIsProgramManagerUserFromAccount.Designer.cs new file mode 100644 index 00000000..52bca3e8 --- /dev/null +++ b/AccountMangement.Infrastructure.EFCore/Migrations/20251213143102_romoveIsProgramManagerUserFromAccount.Designer.cs @@ -0,0 +1,1449 @@ +// +using System; +using AccountMangement.Infrastructure.EFCore; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace AccountMangement.Infrastructure.EFCore.Migrations +{ + [DbContext(typeof(AccountContext))] + [Migration("20251213143102_romoveIsProgramManagerUserFromAccount")] + partial class romoveIsProgramManagerUserFromAccount + { + /// + 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("AccountManagement.Domain.AccountAgg.Account", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("AdminAreaPermission") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.Property("ClientAriaPermission") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .HasMaxLength(150) + .HasColumnType("nvarchar(150)"); + + b.Property("Fullname") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("IsActiveString") + .HasMaxLength(6) + .HasColumnType("nvarchar(6)"); + + b.Property("Mobile") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.Property("NationalCode") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.Property("Password") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("PositionId") + .HasMaxLength(10) + .HasColumnType("bigint"); + + b.Property("PositionIsActive") + .HasMaxLength(5) + .HasColumnType("nvarchar(5)"); + + b.Property("ProfilePhoto") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("RoleId") + .HasColumnType("bigint"); + + b.Property("RoleName") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("Username") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("VerifyCode") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.HasKey("id"); + + b.HasIndex("PositionId"); + + b.HasIndex("RoleId"); + + b.ToTable("Accounts", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.AccountLeftWorkAgg.AccountLeftWork", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("LeftWorkGr") + .HasColumnType("datetime2"); + + b.Property("RoleId") + .HasColumnType("bigint"); + + b.Property("StartWorkGr") + .HasColumnType("datetime2"); + + b.Property("WorkshopId") + .HasColumnType("bigint"); + + b.HasKey("id"); + + b.HasIndex("AccountId"); + + b.ToTable("AccountLeftWork", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.AdminResponseAgg.AdminResponse", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("AdminAccountId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("IsActiveString") + .HasMaxLength(5) + .HasColumnType("nvarchar(5)"); + + b.Property("Response") + .HasColumnType("ntext"); + + b.Property("TicketId") + .HasColumnType("bigint"); + + b.HasKey("id"); + + b.HasIndex("TicketId"); + + b.ToTable("AdminResponses", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.AdminResponseMediaAgg.AdminResponseMedia", b => + { + b.Property("AdminResponseId") + .HasColumnType("bigint"); + + b.Property("MediaId") + .HasColumnType("bigint"); + + b.HasKey("AdminResponseId", "MediaId"); + + b.HasIndex("MediaId"); + + b.ToTable("AdminResponseMedias", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.AssignAgg.Assign", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("AcceptedTimeRequest") + .HasColumnType("int"); + + b.Property("AssignedId") + .HasColumnType("bigint"); + + b.Property("AssignedName") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("AssignedPositionValue") + .HasColumnType("int"); + + b.Property("AssignerId") + .HasColumnType("bigint"); + + b.Property("AssignerPositionValue") + .HasColumnType("int"); + + b.Property("CancelDescription") + .HasColumnType("ntext"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("DoneDescription") + .HasColumnType("ntext"); + + b.Property("EndTaskDate") + .HasColumnType("datetime2"); + + b.Property("FirstTimeCreation") + .HasColumnType("bit"); + + b.Property("IsCancel") + .HasColumnType("bit"); + + b.Property("IsCanceledRequest") + .HasColumnType("bit"); + + b.Property("IsDone") + .HasColumnType("bit"); + + b.Property("IsDoneRequest") + .HasColumnType("bit"); + + b.Property("RequestDate") + .HasColumnType("datetime2"); + + b.Property("TaskId") + .HasColumnType("bigint"); + + b.Property("TimeRequest") + .HasColumnType("bit"); + + b.Property("TimeRequestDescription") + .HasColumnType("ntext"); + + b.HasKey("id"); + + b.HasIndex("TaskId"); + + b.ToTable("Assigns", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.CameraAccountAgg.CameraAccount", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("IsActiveSting") + .IsRequired() + .HasMaxLength(5) + .HasColumnType("nvarchar(5)"); + + b.Property("Mobile") + .HasMaxLength(11) + .HasColumnType("nvarchar(11)"); + + b.Property("Password") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("Username") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("WorkshopId") + .HasColumnType("bigint"); + + b.Property("WorkshopName") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.HasKey("id"); + + b.HasIndex("AccountId"); + + b.ToTable("CameraAccounts", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.ClientResponseAgg.ClientResponse", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Response") + .HasColumnType("ntext"); + + b.Property("TicketId") + .HasColumnType("bigint"); + + b.HasKey("id"); + + b.HasIndex("TicketId"); + + b.ToTable("ClientResponses", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.ClientResponseMediaAgg.ClientResponseMedia", b => + { + b.Property("ClientResponseId") + .HasColumnType("bigint"); + + b.Property("MediaId") + .HasColumnType("bigint"); + + b.HasKey("ClientResponseId", "MediaId"); + + b.HasIndex("MediaId"); + + b.ToTable("ClientResponseMedias", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.MediaAgg.Media", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("Category") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Path") + .HasColumnType("ntext"); + + b.Property("ServiceName") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Type") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.HasKey("id"); + + b.ToTable("Medias", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.PmDomains.PmRoleAgg.PmRole", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("GozareshgirRoleId") + .HasColumnType("bigint"); + + b.Property("RoleName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.HasKey("id"); + + b.ToTable("PmRoles", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("AccountManagement.Domain.PmDomains.PmUserAgg.PmUser", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .HasMaxLength(150) + .HasColumnType("nvarchar(150)"); + + b.Property("FullName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("Mobile") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.Property("Password") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("ProfilePhotoPath") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("VerifyCode") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.HasKey("id"); + + b.ToTable("Users", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.PositionAgg.Position", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("PositionName") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("PositionValue") + .HasMaxLength(2) + .HasColumnType("int"); + + b.HasKey("id"); + + b.ToTable("Positions", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.RoleAgg.Role", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.HasKey("id"); + + b.ToTable("Roles", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.SubAccountAgg.SubAccount", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("FName") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("IsActive") + .IsRequired() + .HasMaxLength(5) + .HasColumnType("nvarchar(5)"); + + b.Property("LName") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("NationalCode") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.Property("Password") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("PhoneNumber") + .IsRequired() + .HasMaxLength(11) + .HasColumnType("nvarchar(11)"); + + b.Property("ProfilePhoto") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("SubAccountRoleId") + .HasColumnType("bigint"); + + b.Property("Username") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("VerifyCode") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.HasKey("id"); + + b.HasIndex("SubAccountRoleId"); + + b.ToTable("SubAccounts", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.SubAccountPermissionSubtitle1Agg.SubAccountPermissionSubtitle1", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("Code") + .HasMaxLength(15) + .HasColumnType("int"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("id"); + + b.ToTable("SubAccountPermissionSubtitle1", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.SubAccountPermissionSubtitle2Agg.SubAccountPermissionSubtitle2", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("Code") + .HasMaxLength(15) + .HasColumnType("int"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("ParentId") + .HasColumnType("bigint"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("id"); + + b.HasIndex("ParentId"); + + b.ToTable("SubAccountPermissionSubtitle2", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.SubAccountPermissionSubtitle3Agg.SubAccountPermissionSubtitle3", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("Code") + .HasMaxLength(15) + .HasColumnType("int"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("ParentId") + .HasColumnType("bigint"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("id"); + + b.HasIndex("ParentId"); + + b.ToTable("SubAccountPermissionSubtitle3", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.SubAccountPermissionSubtitle4Agg.SubAccountPermissionSubtitle4", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("Code") + .HasMaxLength(15) + .HasColumnType("int"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("ParentId") + .HasColumnType("bigint"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("id"); + + b.HasIndex("ParentId"); + + b.ToTable("SubAccountPermissionSubtitle4", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.SubAccountRoleAgg.SubAccountRole", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Title") + .HasMaxLength(60) + .HasColumnType("nvarchar(60)"); + + b.HasKey("id"); + + b.ToTable("SubAccountRoles", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.TaskAgg.Tasks", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("ContractingPartyName") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasColumnType("ntext"); + + b.Property("IsActiveString") + .HasMaxLength(7) + .HasColumnType("nvarchar(7)"); + + b.Property("SenderId") + .HasColumnType("bigint"); + + b.Property("StartTaskDate") + .HasColumnType("datetime2"); + + b.Property("TaskScheduleId") + .HasColumnType("bigint"); + + b.Property("TicketId") + .HasColumnType("bigint"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.HasKey("id"); + + b.HasIndex("TaskScheduleId"); + + b.ToTable("TasksManager", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.TaskMediaAgg.TaskMedia", b => + { + b.Property("MediaId") + .HasColumnType("bigint"); + + b.Property("TaskId") + .HasColumnType("bigint"); + + b.HasKey("MediaId", "TaskId"); + + b.HasIndex("TaskId"); + + b.ToTable("TasksMedias", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.TaskMessageAgg.TaskMessage", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("AssignId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Message") + .HasColumnType("ntext"); + + b.Property("RequestedDateFa") + .HasMaxLength(25) + .HasColumnType("nvarchar(25)"); + + b.Property("TypeOfMessage") + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.HasKey("id"); + + b.HasIndex("AssignId"); + + b.ToTable("TaskMessages", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.TaskMessageItemsAgg.TaskMessageItems", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("ReceiverAccountId") + .HasColumnType("bigint"); + + b.Property("SenderAccountId") + .HasColumnType("bigint"); + + b.Property("TaskMessageId") + .HasColumnType("bigint"); + + b.HasKey("id"); + + b.HasIndex("TaskMessageId"); + + b.ToTable("TaskMessageItems", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.TaskScheduleAgg.TaskSchedule", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("Count") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("IsActive") + .IsRequired() + .HasMaxLength(5) + .HasColumnType("nvarchar(5)"); + + b.Property("LastEndTaskDate") + .HasColumnType("datetime2"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(12) + .HasColumnType("nvarchar(12)"); + + b.Property("UnitNumber") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.Property("UnitType") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.HasKey("id"); + + b.ToTable("TaskSchedules", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.TaskSubjectAgg.TaskSubject", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Subject") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.HasKey("id"); + + b.ToTable("TaskSubjects", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.TicketAccessAccountAgg.TicketAccessAccount", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.HasKey("id"); + + b.ToTable("TicketAccessAccounts", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.TicketAgg.Ticket", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("ContractingPartyName") + .HasMaxLength(155) + .HasColumnType("nvarchar(155)"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasColumnType("ntext"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("SenderId") + .HasColumnType("bigint"); + + b.Property("Status") + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("SubAccountSenderId") + .HasColumnType("bigint"); + + b.Property("TicketNumber") + .HasMaxLength(12) + .HasColumnType("nvarchar(12)"); + + b.Property("TicketType") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Title") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("WorkshopId") + .HasColumnType("bigint"); + + b.HasKey("id"); + + b.ToTable("Tickets", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.TicketMediasAgg.TicketMedia", b => + { + b.Property("TicketId") + .HasColumnType("bigint"); + + b.Property("MediaId") + .HasColumnType("bigint"); + + b.HasKey("TicketId", "MediaId"); + + b.HasIndex("MediaId"); + + b.ToTable("TicketMedias", (string)null); + }); + + modelBuilder.Entity("AccountManagement.Domain.AccountAgg.Account", b => + { + b.HasOne("AccountManagement.Domain.PositionAgg.Position", "Position") + .WithMany("Accounts") + .HasForeignKey("PositionId"); + + b.HasOne("AccountManagement.Domain.RoleAgg.Role", "Role") + .WithMany("Accounts") + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Position"); + + b.Navigation("Role"); + }); + + modelBuilder.Entity("AccountManagement.Domain.AccountLeftWorkAgg.AccountLeftWork", b => + { + b.HasOne("AccountManagement.Domain.AccountAgg.Account", "Account") + .WithMany("AccountLeftWorkList") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("AccountManagement.Domain.AdminResponseAgg.AdminResponse", b => + { + b.HasOne("AccountManagement.Domain.TicketAgg.Ticket", "Ticket") + .WithMany("AdminResponses") + .HasForeignKey("TicketId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Ticket"); + }); + + modelBuilder.Entity("AccountManagement.Domain.AdminResponseMediaAgg.AdminResponseMedia", b => + { + b.HasOne("AccountManagement.Domain.AdminResponseAgg.AdminResponse", "AdminResponse") + .WithMany("AdminResponseMedias") + .HasForeignKey("AdminResponseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AccountManagement.Domain.MediaAgg.Media", "Media") + .WithMany("AdminResponseMedias") + .HasForeignKey("MediaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("AdminResponse"); + + b.Navigation("Media"); + }); + + modelBuilder.Entity("AccountManagement.Domain.AssignAgg.Assign", b => + { + b.HasOne("AccountManagement.Domain.TaskAgg.Tasks", "Task") + .WithMany("Assigns") + .HasForeignKey("TaskId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("AccountManagement.Domain.CameraAccountAgg.CameraAccount", b => + { + b.HasOne("AccountManagement.Domain.AccountAgg.Account", "Account") + .WithMany("CameraAccounts") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("AccountManagement.Domain.ClientResponseAgg.ClientResponse", b => + { + b.HasOne("AccountManagement.Domain.TicketAgg.Ticket", "Ticket") + .WithMany("ClientResponses") + .HasForeignKey("TicketId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Ticket"); + }); + + modelBuilder.Entity("AccountManagement.Domain.ClientResponseMediaAgg.ClientResponseMedia", b => + { + b.HasOne("AccountManagement.Domain.ClientResponseAgg.ClientResponse", "ClientResponse") + .WithMany("ClientResponseMedias") + .HasForeignKey("ClientResponseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AccountManagement.Domain.MediaAgg.Media", "Media") + .WithMany("ClientResponseMedias") + .HasForeignKey("MediaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ClientResponse"); + + b.Navigation("Media"); + }); + + modelBuilder.Entity("AccountManagement.Domain.PmDomains.PmRoleAgg.PmRole", b => + { + b.OwnsMany("AccountManagement.Domain.PmDomains.PmPermissionAgg.PmPermission", "PmPermission", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("Code") + .HasColumnType("int"); + + b1.Property("Roleid") + .HasColumnType("bigint"); + + b1.HasKey("Id"); + + b1.HasIndex("Roleid"); + + b1.ToTable("PmRolePermissions", null, t => + { + t.ExcludeFromMigrations(); + }); + + b1.WithOwner("Role") + .HasForeignKey("Roleid"); + + b1.Navigation("Role"); + }); + + b.Navigation("PmPermission"); + }); + + modelBuilder.Entity("AccountManagement.Domain.PmDomains.PmUserAgg.PmUser", b => + { + b.OwnsMany("AccountManagement.Domain.PmDomains.PmRoleUserAgg.PmRoleUser", "RoleUser", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("RoleId") + .HasColumnType("bigint"); + + b1.Property("Userid") + .HasColumnType("bigint"); + + b1.HasKey("Id"); + + b1.HasIndex("Userid"); + + b1.ToTable("RoleUsers", (string)null); + + b1.WithOwner("User") + .HasForeignKey("Userid"); + + b1.Navigation("User"); + }); + + b.Navigation("RoleUser"); + }); + + modelBuilder.Entity("AccountManagement.Domain.RoleAgg.Role", b => + { + b.OwnsMany("AccountManagement.Domain.RoleAgg.Permission", "Permissions", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("Code") + .HasColumnType("int"); + + b1.Property("RoleId") + .HasColumnType("bigint"); + + b1.HasKey("Id"); + + b1.HasIndex("RoleId"); + + b1.ToTable("RolePermissions", (string)null); + + b1.WithOwner("Role") + .HasForeignKey("RoleId"); + + b1.Navigation("Role"); + }); + + b.Navigation("Permissions"); + }); + + modelBuilder.Entity("AccountManagement.Domain.SubAccountAgg.SubAccount", b => + { + b.HasOne("AccountManagement.Domain.SubAccountRoleAgg.SubAccountRole", "SubAccountRole") + .WithMany("SubAccounts") + .HasForeignKey("SubAccountRoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("SubAccountRole"); + }); + + modelBuilder.Entity("AccountManagement.Domain.SubAccountPermissionSubtitle2Agg.SubAccountPermissionSubtitle2", b => + { + b.HasOne("AccountManagement.Domain.SubAccountPermissionSubtitle1Agg.SubAccountPermissionSubtitle1", "Parent") + .WithMany("Children") + .HasForeignKey("ParentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Parent"); + }); + + modelBuilder.Entity("AccountManagement.Domain.SubAccountPermissionSubtitle3Agg.SubAccountPermissionSubtitle3", b => + { + b.HasOne("AccountManagement.Domain.SubAccountPermissionSubtitle2Agg.SubAccountPermissionSubtitle2", "Parent") + .WithMany("Children") + .HasForeignKey("ParentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Parent"); + }); + + modelBuilder.Entity("AccountManagement.Domain.SubAccountPermissionSubtitle4Agg.SubAccountPermissionSubtitle4", b => + { + b.HasOne("AccountManagement.Domain.SubAccountPermissionSubtitle3Agg.SubAccountPermissionSubtitle3", "Parent") + .WithMany("Children") + .HasForeignKey("ParentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Parent"); + }); + + modelBuilder.Entity("AccountManagement.Domain.SubAccountRoleAgg.SubAccountRole", b => + { + b.OwnsMany("AccountManagement.Domain.SubAccountRoleAgg.SubAccountRoleWorkshop", "RoleWorkshops", b1 => + { + b1.Property("SubAccountId") + .HasColumnType("bigint"); + + b1.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("id")); + + b1.Property("CreationDate") + .HasColumnType("datetime2"); + + b1.Property("WorkshopId") + .HasColumnType("bigint"); + + b1.HasKey("SubAccountId", "id"); + + b1.ToTable("SubAccountRoleWorkshop"); + + b1.WithOwner("SubAccountRole") + .HasForeignKey("SubAccountId"); + + b1.Navigation("SubAccountRole"); + }); + + b.OwnsMany("AccountManagement.Domain.SubAccountRoleAgg.SubAccountRolePermission", "RolePermissions", b1 => + { + b1.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("id")); + + b1.Property("PermissionCode") + .HasColumnType("int"); + + b1.Property("SubAccountRoleId") + .HasColumnType("bigint"); + + b1.HasKey("id"); + + b1.HasIndex("SubAccountRoleId"); + + b1.ToTable("SubAccountRolePermissions", (string)null); + + b1.WithOwner("SubAccountRole") + .HasForeignKey("SubAccountRoleId"); + + b1.Navigation("SubAccountRole"); + }); + + b.Navigation("RolePermissions"); + + b.Navigation("RoleWorkshops"); + }); + + modelBuilder.Entity("AccountManagement.Domain.TaskAgg.Tasks", b => + { + b.HasOne("AccountManagement.Domain.TaskScheduleAgg.TaskSchedule", "TaskSchedule") + .WithMany("TasksList") + .HasForeignKey("TaskScheduleId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("TaskSchedule"); + }); + + modelBuilder.Entity("AccountManagement.Domain.TaskMediaAgg.TaskMedia", b => + { + b.HasOne("AccountManagement.Domain.MediaAgg.Media", "Media") + .WithMany("TaskMedias") + .HasForeignKey("MediaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AccountManagement.Domain.TaskAgg.Tasks", "Tasks") + .WithMany("TaskMedias") + .HasForeignKey("TaskId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Media"); + + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("AccountManagement.Domain.TaskMessageAgg.TaskMessage", b => + { + b.HasOne("AccountManagement.Domain.AssignAgg.Assign", "Assign") + .WithMany("TaskMessageList") + .HasForeignKey("AssignId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Assign"); + }); + + modelBuilder.Entity("AccountManagement.Domain.TaskMessageItemsAgg.TaskMessageItems", b => + { + b.HasOne("AccountManagement.Domain.TaskMessageAgg.TaskMessage", "TaskMessage") + .WithMany("TaskMessageItemsList") + .HasForeignKey("TaskMessageId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("TaskMessage"); + }); + + modelBuilder.Entity("AccountManagement.Domain.TicketMediasAgg.TicketMedia", b => + { + b.HasOne("AccountManagement.Domain.MediaAgg.Media", "Media") + .WithMany("TicketMedias") + .HasForeignKey("MediaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AccountManagement.Domain.TicketAgg.Ticket", "Ticket") + .WithMany("TicketMedias") + .HasForeignKey("TicketId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Media"); + + b.Navigation("Ticket"); + }); + + modelBuilder.Entity("AccountManagement.Domain.AccountAgg.Account", b => + { + b.Navigation("AccountLeftWorkList"); + + b.Navigation("CameraAccounts"); + }); + + modelBuilder.Entity("AccountManagement.Domain.AdminResponseAgg.AdminResponse", b => + { + b.Navigation("AdminResponseMedias"); + }); + + modelBuilder.Entity("AccountManagement.Domain.AssignAgg.Assign", b => + { + b.Navigation("TaskMessageList"); + }); + + modelBuilder.Entity("AccountManagement.Domain.ClientResponseAgg.ClientResponse", b => + { + b.Navigation("ClientResponseMedias"); + }); + + modelBuilder.Entity("AccountManagement.Domain.MediaAgg.Media", b => + { + b.Navigation("AdminResponseMedias"); + + b.Navigation("ClientResponseMedias"); + + b.Navigation("TaskMedias"); + + b.Navigation("TicketMedias"); + }); + + modelBuilder.Entity("AccountManagement.Domain.PositionAgg.Position", b => + { + b.Navigation("Accounts"); + }); + + modelBuilder.Entity("AccountManagement.Domain.RoleAgg.Role", b => + { + b.Navigation("Accounts"); + }); + + modelBuilder.Entity("AccountManagement.Domain.SubAccountPermissionSubtitle1Agg.SubAccountPermissionSubtitle1", b => + { + b.Navigation("Children"); + }); + + modelBuilder.Entity("AccountManagement.Domain.SubAccountPermissionSubtitle2Agg.SubAccountPermissionSubtitle2", b => + { + b.Navigation("Children"); + }); + + modelBuilder.Entity("AccountManagement.Domain.SubAccountPermissionSubtitle3Agg.SubAccountPermissionSubtitle3", b => + { + b.Navigation("Children"); + }); + + modelBuilder.Entity("AccountManagement.Domain.SubAccountRoleAgg.SubAccountRole", b => + { + b.Navigation("SubAccounts"); + }); + + modelBuilder.Entity("AccountManagement.Domain.TaskAgg.Tasks", b => + { + b.Navigation("Assigns"); + + b.Navigation("TaskMedias"); + }); + + modelBuilder.Entity("AccountManagement.Domain.TaskMessageAgg.TaskMessage", b => + { + b.Navigation("TaskMessageItemsList"); + }); + + modelBuilder.Entity("AccountManagement.Domain.TaskScheduleAgg.TaskSchedule", b => + { + b.Navigation("TasksList"); + }); + + modelBuilder.Entity("AccountManagement.Domain.TicketAgg.Ticket", b => + { + b.Navigation("AdminResponses"); + + b.Navigation("ClientResponses"); + + b.Navigation("TicketMedias"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/AccountMangement.Infrastructure.EFCore/Migrations/20251213143102_romoveIsProgramManagerUserFromAccount.cs b/AccountMangement.Infrastructure.EFCore/Migrations/20251213143102_romoveIsProgramManagerUserFromAccount.cs new file mode 100644 index 00000000..2a3a5929 --- /dev/null +++ b/AccountMangement.Infrastructure.EFCore/Migrations/20251213143102_romoveIsProgramManagerUserFromAccount.cs @@ -0,0 +1,29 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace AccountMangement.Infrastructure.EFCore.Migrations +{ + /// + public partial class romoveIsProgramManagerUserFromAccount : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "IsProgramManagerUser", + table: "Accounts"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "IsProgramManagerUser", + table: "Accounts", + type: "bit", + nullable: false, + defaultValue: false); + } + } +} diff --git a/AccountMangement.Infrastructure.EFCore/Migrations/AccountContextModelSnapshot.cs b/AccountMangement.Infrastructure.EFCore/Migrations/AccountContextModelSnapshot.cs index 44a0ebd1..800be041 100644 --- a/AccountMangement.Infrastructure.EFCore/Migrations/AccountContextModelSnapshot.cs +++ b/AccountMangement.Infrastructure.EFCore/Migrations/AccountContextModelSnapshot.cs @@ -17,7 +17,7 @@ namespace AccountMangement.Infrastructure.EFCore.Migrations { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "8.0.10") + .HasAnnotation("ProductVersion", "10.0.1") .HasAnnotation("Relational:MaxIdentifierLength", 128); SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); @@ -377,6 +377,87 @@ namespace AccountMangement.Infrastructure.EFCore.Migrations b.ToTable("Medias", (string)null); }); + modelBuilder.Entity("AccountManagement.Domain.PmDomains.PmRoleAgg.PmRole", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("GozareshgirRoleId") + .HasColumnType("bigint"); + + b.Property("RoleName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.HasKey("id"); + + b.ToTable("PmRoles", null, t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("AccountManagement.Domain.PmDomains.PmUserAgg.PmUser", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("id")); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .HasMaxLength(150) + .HasColumnType("nvarchar(150)"); + + b.Property("FullName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("Mobile") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.Property("Password") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("ProfilePhotoPath") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("VerifyCode") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.HasKey("id"); + + b.ToTable("Users", (string)null); + }); + modelBuilder.Entity("AccountManagement.Domain.PositionAgg.Position", b => { b.Property("id") @@ -1001,6 +1082,71 @@ namespace AccountMangement.Infrastructure.EFCore.Migrations b.Navigation("Media"); }); + modelBuilder.Entity("AccountManagement.Domain.PmDomains.PmRoleAgg.PmRole", b => + { + b.OwnsMany("AccountManagement.Domain.PmDomains.PmPermissionAgg.PmPermission", "PmPermission", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("Code") + .HasColumnType("int"); + + b1.Property("Roleid") + .HasColumnType("bigint"); + + b1.HasKey("Id"); + + b1.HasIndex("Roleid"); + + b1.ToTable("PmRolePermissions", null, t => + { + t.ExcludeFromMigrations(); + }); + + b1.WithOwner("Role") + .HasForeignKey("Roleid"); + + b1.Navigation("Role"); + }); + + b.Navigation("PmPermission"); + }); + + modelBuilder.Entity("AccountManagement.Domain.PmDomains.PmUserAgg.PmUser", b => + { + b.OwnsMany("AccountManagement.Domain.PmDomains.PmRoleUserAgg.PmRoleUser", "RoleUser", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("RoleId") + .HasColumnType("bigint"); + + b1.Property("Userid") + .HasColumnType("bigint"); + + b1.HasKey("Id"); + + b1.HasIndex("Userid"); + + b1.ToTable("RoleUsers", (string)null); + + b1.WithOwner("User") + .HasForeignKey("Userid"); + + b1.Navigation("User"); + }); + + b.Navigation("RoleUser"); + }); + modelBuilder.Entity("AccountManagement.Domain.RoleAgg.Role", b => { b.OwnsMany("AccountManagement.Domain.RoleAgg.Permission", "Permissions", b1 => diff --git a/BackgroundInstitutionContract/BackgroundInstitutionContract.Task/BackgroundInstitutionContract.Task.csproj b/BackgroundInstitutionContract/BackgroundInstitutionContract.Task/BackgroundInstitutionContract.Task.csproj index d30ce3b8..d003ac92 100644 --- a/BackgroundInstitutionContract/BackgroundInstitutionContract.Task/BackgroundInstitutionContract.Task.csproj +++ b/BackgroundInstitutionContract/BackgroundInstitutionContract.Task/BackgroundInstitutionContract.Task.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 enable enable BackgroundInstitutionContract.Task diff --git a/BackgroundJobs/BackgroundJobs.Task/BackgroundJobs.Task.csproj b/BackgroundJobs/BackgroundJobs.Task/BackgroundJobs.Task.csproj index 0ab571f8..892e6b99 100644 --- a/BackgroundJobs/BackgroundJobs.Task/BackgroundJobs.Task.csproj +++ b/BackgroundJobs/BackgroundJobs.Task/BackgroundJobs.Task.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 enable enable diff --git a/Company.Domain/Company.Domain.csproj b/Company.Domain/Company.Domain.csproj index 924cc212..43b665be 100644 --- a/Company.Domain/Company.Domain.csproj +++ b/Company.Domain/Company.Domain.csproj @@ -1,7 +1,7 @@  - net8.0 + net10.0 @@ -20,7 +20,11 @@ - + + + + + diff --git a/CompanyManagement.Infrastructure.Excel/CompanyManagement.Infrastructure.Excel.csproj b/CompanyManagement.Infrastructure.Excel/CompanyManagement.Infrastructure.Excel.csproj index a62b92f9..67ee0926 100644 --- a/CompanyManagement.Infrastructure.Excel/CompanyManagement.Infrastructure.Excel.csproj +++ b/CompanyManagement.Infrastructure.Excel/CompanyManagement.Infrastructure.Excel.csproj @@ -1,13 +1,14 @@  - net8.0 + net10.0 enable enable - - + + + diff --git a/CompanyManagement.Infrastructure.Mongo/CompanyManagement.Infrastructure.Mongo.csproj b/CompanyManagement.Infrastructure.Mongo/CompanyManagement.Infrastructure.Mongo.csproj index 4c09d4ae..6840ab15 100644 --- a/CompanyManagement.Infrastructure.Mongo/CompanyManagement.Infrastructure.Mongo.csproj +++ b/CompanyManagement.Infrastructure.Mongo/CompanyManagement.Infrastructure.Mongo.csproj @@ -1,7 +1,7 @@  - net8.0 + net10.0 enable enable @@ -11,7 +11,8 @@ - + + diff --git a/CompanyManagment.App.Contracts/CompanyManagment.App.Contracts.csproj b/CompanyManagment.App.Contracts/CompanyManagment.App.Contracts.csproj index b2977176..460093f3 100644 --- a/CompanyManagment.App.Contracts/CompanyManagment.App.Contracts.csproj +++ b/CompanyManagment.App.Contracts/CompanyManagment.App.Contracts.csproj @@ -1,12 +1,16 @@  - net8.0 + net10.0 true + + + + diff --git a/CompanyManagment.Application/CompanyManagment.Application.csproj b/CompanyManagment.Application/CompanyManagment.Application.csproj index 36154b43..f6e0f038 100644 --- a/CompanyManagment.Application/CompanyManagment.Application.csproj +++ b/CompanyManagment.Application/CompanyManagment.Application.csproj @@ -1,12 +1,13 @@ - net8.0 + net10.0 - + + diff --git a/CompanyManagment.EFCore/CompanyManagment.EFCore.csproj b/CompanyManagment.EFCore/CompanyManagment.EFCore.csproj index 7ea4c3cd..ff272f51 100644 --- a/CompanyManagment.EFCore/CompanyManagment.EFCore.csproj +++ b/CompanyManagment.EFCore/CompanyManagment.EFCore.csproj @@ -1,18 +1,20 @@  - net8.0 + net10.0 - - - + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + diff --git a/CompanyManagment.EFCore/Services/HolidayQueryService.cs b/CompanyManagment.EFCore/Services/HolidayQueryService.cs new file mode 100644 index 00000000..4b8aa51c --- /dev/null +++ b/CompanyManagment.EFCore/Services/HolidayQueryService.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Shared.Contracts.Holidays; + +namespace CompanyManagment.EFCore.Services; + +public class HolidayQueryService : IHolidayQueryService +{ + public Task> GetHolidaysInDates(DateTime startDate, DateTime endDate) + { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/DadmehrGostar.sln b/DadmehrGostar.sln index b6cf7ab9..f31d5bcb 100644 --- a/DadmehrGostar.sln +++ b/DadmehrGostar.sln @@ -88,6 +88,24 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CompanyManagement.Infrastru EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BackgroundInstitutionContract.Task", "BackgroundInstitutionContract\BackgroundInstitutionContract.Task\BackgroundInstitutionContract.Task.csproj", "{F78FBB92-294B-88BA-168D-F0C578B0D7D6}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ProgramManager", "ProgramManager", "{67AFF7B6-4C4F-464C-A90D-9BDB644D83A9}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{48F6F6A5-7340-42F8-9216-BEB7A4B7D5A1}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Application", "Application", "{9D85672B-D48E-40B5-9804-0CE220E0E64C}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Domain", "Domain", "{D74D1E3B-3BE3-47EE-9914-785A8AD536E5}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Infrastructure", "Infrastructure", "{C0AE9368-D4E7-450B-9713-929D319DE690}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GozareshgirProgramManager.Application", "ProgramManager\src\Application\GozareshgirProgramManager.Application\GozareshgirProgramManager.Application.csproj", "{B57EB542-C028-4A77-9386-9DFF1E60FDCB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GozareshgirProgramManager.Domain", "ProgramManager\src\Domain\GozareshgirProgramManager.Domain\GozareshgirProgramManager.Domain.csproj", "{D2B4F1D7-6336-4B30-910C-219F4119303F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GozareshgirProgramManager.Infrastructure", "ProgramManager\src\Infrastructure\GozareshgirProgramManager.Infrastructure\GozareshgirProgramManager.Infrastructure.csproj", "{408281FE-615F-4CBE-BD95-2E86F5ACC6C3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shared.Contracts", "Shared.Contracts\Shared.Contracts.csproj", "{08B234B6-783B-44E9-9961-4F97EAD16308}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -198,6 +216,22 @@ Global {F78FBB92-294B-88BA-168D-F0C578B0D7D6}.Debug|Any CPU.Build.0 = Debug|Any CPU {F78FBB92-294B-88BA-168D-F0C578B0D7D6}.Release|Any CPU.ActiveCfg = Release|Any CPU {F78FBB92-294B-88BA-168D-F0C578B0D7D6}.Release|Any CPU.Build.0 = Release|Any CPU + {B57EB542-C028-4A77-9386-9DFF1E60FDCB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B57EB542-C028-4A77-9386-9DFF1E60FDCB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B57EB542-C028-4A77-9386-9DFF1E60FDCB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B57EB542-C028-4A77-9386-9DFF1E60FDCB}.Release|Any CPU.Build.0 = Release|Any CPU + {D2B4F1D7-6336-4B30-910C-219F4119303F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D2B4F1D7-6336-4B30-910C-219F4119303F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D2B4F1D7-6336-4B30-910C-219F4119303F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D2B4F1D7-6336-4B30-910C-219F4119303F}.Release|Any CPU.Build.0 = Release|Any CPU + {408281FE-615F-4CBE-BD95-2E86F5ACC6C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {408281FE-615F-4CBE-BD95-2E86F5ACC6C3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {408281FE-615F-4CBE-BD95-2E86F5ACC6C3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {408281FE-615F-4CBE-BD95-2E86F5ACC6C3}.Release|Any CPU.Build.0 = Release|Any CPU + {08B234B6-783B-44E9-9961-4F97EAD16308}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {08B234B6-783B-44E9-9961-4F97EAD16308}.Debug|Any CPU.Build.0 = Debug|Any CPU + {08B234B6-783B-44E9-9961-4F97EAD16308}.Release|Any CPU.ActiveCfg = Release|Any CPU + {08B234B6-783B-44E9-9961-4F97EAD16308}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -234,6 +268,13 @@ Global {BF98173C-42AF-4897-A7CB-4CACEB2B52A2} = {86921E1B-2AFA-4B8A-9403-EE16D58B5B26} {97E148FA-3C36-40DD-B121-D90C1C0F3B47} = {C10E256D-7E7D-4C77-B416-E577A34AF924} {F78FBB92-294B-88BA-168D-F0C578B0D7D6} = {C10E256D-7E7D-4C77-B416-E577A34AF924} + {48F6F6A5-7340-42F8-9216-BEB7A4B7D5A1} = {67AFF7B6-4C4F-464C-A90D-9BDB644D83A9} + {9D85672B-D48E-40B5-9804-0CE220E0E64C} = {48F6F6A5-7340-42F8-9216-BEB7A4B7D5A1} + {D74D1E3B-3BE3-47EE-9914-785A8AD536E5} = {48F6F6A5-7340-42F8-9216-BEB7A4B7D5A1} + {C0AE9368-D4E7-450B-9713-929D319DE690} = {48F6F6A5-7340-42F8-9216-BEB7A4B7D5A1} + {B57EB542-C028-4A77-9386-9DFF1E60FDCB} = {9D85672B-D48E-40B5-9804-0CE220E0E64C} + {D2B4F1D7-6336-4B30-910C-219F4119303F} = {D74D1E3B-3BE3-47EE-9914-785A8AD536E5} + {408281FE-615F-4CBE-BD95-2E86F5ACC6C3} = {C0AE9368-D4E7-450B-9713-929D319DE690} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E6CFB3A7-A7C8-4E82-8F06-F750408F0BA9} diff --git a/PersonalContractingParty.Config/PersonalBootstrapper.cs b/PersonalContractingParty.Config/PersonalBootstrapper.cs index 19bd81ac..ebb0e49f 100644 --- a/PersonalContractingParty.Config/PersonalBootstrapper.cs +++ b/PersonalContractingParty.Config/PersonalBootstrapper.cs @@ -1,18 +1,44 @@ -using System; +using _0_Framework.Application.FaceEmbedding; using _0_Framework.Application.UID; +using _0_Framework.Infrastructure; +using _0_Framework.InfraStructure; using Company.Application.Contracts.AuthorizedBankDetails; +using Company.Domain._common; +using Company.Domain.AdminMonthlyOverviewAgg; +using Company.Domain.AndroidApkVersionAgg; +using Company.Domain.AuthorizedBankDetailsAgg; +using Company.Domain.AuthorizedPersonAgg; +using Company.Domain.BankAgg; using Company.Domain.BillAgg; using Company.Domain.Board; using Company.Domain.ChapterAgg; using Company.Domain.CheckoutAgg; using Company.Domain.ClassifiedSalaryAgg; using Company.Domain.Contact2Agg; -using Company.Domain.CrossJobAgg; -using Company.Domain.CrossJobGuildAgg; +using Company.Domain.ContactUsAgg; using Company.Domain.ContarctingPartyAgg; using Company.Domain.ContractAgg; +using Company.Domain.ContractingPartyBankAccountsAgg; +using Company.Domain.CrossJobAgg; +using Company.Domain.CrossJobGuildAgg; +using Company.Domain.CrossJobItemsAgg; +using Company.Domain.CustomizeCheckoutAgg; +using Company.Domain.CustomizeCheckoutTempAgg; +using Company.Domain.CustomizeWorkshopEmployeeSettingsAgg; +using Company.Domain.CustomizeWorkshopGroupSettingsAgg; +using Company.Domain.CustomizeWorkshopSettingsAgg; +using Company.Domain.DateSalaryAgg; +using Company.Domain.DateSalaryItemAgg; using Company.Domain.EmployeeAgg; +using Company.Domain.EmployeeAuthorizeTempAgg; +using Company.Domain.EmployeeBankInformationAgg; using Company.Domain.EmployeeChildrenAgg; +using Company.Domain.EmployeeClientTempAgg; +using Company.Domain.EmployeeComputeOptionsAgg; +using Company.Domain.EmployeeDocumentItemAgg; +using Company.Domain.EmployeeDocumentsAdminSelectionAgg; +using Company.Domain.EmployeeDocumentsAgg; +using Company.Domain.EmployeeFaceEmbeddingAgg; using Company.Domain.empolyerAgg; using Company.Domain.Evidence; using Company.Domain.EvidenceDetail; @@ -23,38 +49,108 @@ using Company.Domain.FileEmployerAgg; using Company.Domain.FileState; using Company.Domain.FileTiming; using Company.Domain.FileTitle; +using Company.Domain.FinancialInvoiceAgg; +using Company.Domain.FinancialStatmentAgg; +using Company.Domain.FinancialTransactionAgg; +using Company.Domain.FineAgg; +using Company.Domain.FineSubjectAgg; +using Company.Domain.GroupPlanAgg; +using Company.Domain.GroupPlanJobItemAgg; using Company.Domain.HolidayAgg; using Company.Domain.HolidayItemAgg; +using Company.Domain.InstitutionContractAgg; +using Company.Domain.InstitutionContractContactInfoAgg; +using Company.Domain.InstitutionContractExtensionTempAgg; +using Company.Domain.InstitutionPlanAgg; +using Company.Domain.InsuranceAgg; +using Company.Domain.InsuranceEmployeeInfoAgg; +using Company.Domain.InsuranceJobItemAgg; +using Company.Domain.InsuranceListAgg; +using Company.Domain.InsuranceYearlySalaryAgg; +using Company.Domain.InsurancJobAgg; +using Company.Domain.InsurancWorkshopInfoAgg; using Company.Domain.JobAgg; +using Company.Domain.LawAgg; using Company.Domain.LeaveAgg; using Company.Domain.LeftWorkAgg; +using Company.Domain.LeftWorkInsuranceAgg; +using Company.Domain.LeftWorkTempAgg; +using Company.Domain.LoanAgg; using Company.Domain.MandatoryHoursAgg; using Company.Domain.MasterPenaltyTitle; using Company.Domain.MasterPetition; using Company.Domain.MasterWorkHistory; using Company.Domain.ModuleAgg; using Company.Domain.OriginalTitleAgg; +using Company.Domain.PaymentInstrumentAgg; +using Company.Domain.PaymentToEmployeeAgg; +using Company.Domain.PaymentToEmployeeItemAgg; +using Company.Domain.PaymentTransactionAgg; using Company.Domain.PenaltyTitle; +using Company.Domain.PercentageAgg; +using Company.Domain.PersonnelCodeAgg; using Company.Domain.Petition; using Company.Domain.ProceedingSession; +using Company.Domain.ReportAgg; +using Company.Domain.ReportClientAgg; using Company.Domain.RepresentativeAgg; +using Company.Domain.RewardAgg; +using Company.Domain.RollCallAgg; +using Company.Domain.RollCallAgg.DomainService; +using Company.Domain.RollCallEmployeeAgg; +using Company.Domain.RollCallEmployeeStatusAgg; +using Company.Domain.RollCallPlanAgg; +using Company.Domain.RollCallServiceAgg; +using Company.Domain.SalaryAidAgg; +using Company.Domain.SmsResultAgg; using Company.Domain.SubtitleAgg; +using Company.Domain.TaxJobCategoryAgg; +using Company.Domain.TemporaryClientRegistrationAgg; using Company.Domain.WorkHistory; using Company.Domain.WorkingHoursAgg; using Company.Domain.WorkingHoursItemsAgg; +using Company.Domain.WorkingHoursTempAgg; +using Company.Domain.WorkingHoursTempItemAgg; +using Company.Domain.WorkshopAccountAgg; using Company.Domain.WorkshopAgg; +using Company.Domain.WorkshopPlanAgg; +using Company.Domain.WorkshopPlanEmployeeAgg; +using Company.Domain.WorkshopSubAccountAgg; using Company.Domain.YearlySalaryAgg; using Company.Domain.YearlySalaryItemsAgg; using Company.Domain.YearlysSalaryTitleAgg; +using Company.Domain.ZoneAgg; +using CompanyManagement.Infrastructure.Excel.SalaryAid; +using CompanyManagement.Infrastructure.Mongo.EmployeeFaceEmbeddingRepo; +using CompanyManagement.Infrastructure.Mongo.InstitutionContractInsertTempRepo; +using CompanyManagment.App.Contracts.AdminMonthlyOverview; +using CompanyManagment.App.Contracts.AndroidApkVersion; +using CompanyManagment.App.Contracts.AuthorizedPerson; +using CompanyManagment.App.Contracts.Bank; using CompanyManagment.App.Contracts.Board; using CompanyManagment.App.Contracts.Chapter; using CompanyManagment.App.Contracts.Checkout; +using CompanyManagment.App.Contracts.ClassifiedSalary; using CompanyManagment.App.Contracts.Contact2; +using CompanyManagment.App.Contracts.ContactUs; using CompanyManagment.App.Contracts.Contract; +using CompanyManagment.App.Contracts.ContractingPartyBankAccounts; using CompanyManagment.App.Contracts.CrossJob; using CompanyManagment.App.Contracts.CrossJobGuild; +using CompanyManagment.App.Contracts.CrossJobItems; +using CompanyManagment.App.Contracts.CustomizeCheckout; +using CompanyManagment.App.Contracts.CustomizeWorkshopSettings; +using CompanyManagment.App.Contracts.DateSalary; +using CompanyManagment.App.Contracts.DateSalaryItem; using CompanyManagment.App.Contracts.Employee; +using CompanyManagment.App.Contracts.EmployeeBankInformation; using CompanyManagment.App.Contracts.EmployeeChildren; +using CompanyManagment.App.Contracts.EmployeeClientTemp; +using CompanyManagment.App.Contracts.EmployeeComputeOptions; +using CompanyManagment.App.Contracts.EmployeeDocuments; +using CompanyManagment.App.Contracts.EmployeeDocumentsAdminSelection; +using CompanyManagment.App.Contracts.EmployeeFaceEmbedding; +using CompanyManagment.App.Contracts.EmployeeInsurancListData; using CompanyManagment.App.Contracts.Employer; using CompanyManagment.App.Contracts.Evidence; using CompanyManagment.App.Contracts.EvidenceDetail; @@ -65,33 +161,74 @@ using CompanyManagment.App.Contracts.FileEmployer; using CompanyManagment.App.Contracts.FileState; using CompanyManagment.App.Contracts.FileTiming; using CompanyManagment.App.Contracts.FileTitle; +using CompanyManagment.App.Contracts.FinancialInvoice; +using CompanyManagment.App.Contracts.FinancialStatment; +using CompanyManagment.App.Contracts.FinancilTransaction; +using CompanyManagment.App.Contracts.Fine; +using CompanyManagment.App.Contracts.FineSubject; using CompanyManagment.App.Contracts.Holiday; using CompanyManagment.App.Contracts.HolidayItem; +using CompanyManagment.App.Contracts.InstitutionContract; +using CompanyManagment.App.Contracts.InstitutionContractContactinfo; +using CompanyManagment.App.Contracts.InstitutionPlan; +using CompanyManagment.App.Contracts.Insurance; +using CompanyManagment.App.Contracts.InsuranceEmployeeInfo; +using CompanyManagment.App.Contracts.InsuranceJob; +using CompanyManagment.App.Contracts.InsuranceList; +using CompanyManagment.App.Contracts.InsuranceWorkshopInfo; +using CompanyManagment.App.Contracts.InsuranceYearlySalary; using CompanyManagment.App.Contracts.Job; +using CompanyManagment.App.Contracts.Law; using CompanyManagment.App.Contracts.Leave; using CompanyManagment.App.Contracts.LeftWork; +using CompanyManagment.App.Contracts.LeftWorkInsurance; +using CompanyManagment.App.Contracts.LeftWorkTemp; +using CompanyManagment.App.Contracts.Loan; using CompanyManagment.App.Contracts.MandantoryHours; using CompanyManagment.App.Contracts.MasterPenaltyTitle; using CompanyManagment.App.Contracts.MasterPetition; using CompanyManagment.App.Contracts.MasterWorkHistory; using CompanyManagment.App.Contracts.Module; using CompanyManagment.App.Contracts.OriginalTitle; +using CompanyManagment.App.Contracts.PaymentInstrument; +using CompanyManagment.App.Contracts.PaymentToEmployee; +using CompanyManagment.App.Contracts.PaymentTransaction; using CompanyManagment.App.Contracts.PenaltyTitle; +using CompanyManagment.App.Contracts.Percentage; using CompanyManagment.App.Contracts.PersonalContractingParty; +using CompanyManagment.App.Contracts.PersonnleCode; using CompanyManagment.App.Contracts.Petition; using CompanyManagment.App.Contracts.ProceedingSession; +using CompanyManagment.App.Contracts.Report; +using CompanyManagment.App.Contracts.ReportClient; using CompanyManagment.App.Contracts.Representative; +using CompanyManagment.App.Contracts.Reward; +using CompanyManagment.App.Contracts.RollCall; +using CompanyManagment.App.Contracts.RollCallEmployee; +using CompanyManagment.App.Contracts.RollCallEmployeeStatus; +using CompanyManagment.App.Contracts.RollCallPlan; +using CompanyManagment.App.Contracts.RollCallService; +using CompanyManagment.App.Contracts.SalaryAid; +using CompanyManagment.App.Contracts.SmsResult; using CompanyManagment.App.Contracts.Subtitle; +using CompanyManagment.App.Contracts.TaxJobCategory; +using CompanyManagment.App.Contracts.TemporaryClientRegistration; using CompanyManagment.App.Contracts.TextManager; using CompanyManagment.App.Contracts.WorkHistory; using CompanyManagment.App.Contracts.WorkingHours; using CompanyManagment.App.Contracts.WorkingHoursItems; +using CompanyManagment.App.Contracts.WorkingHoursTemp; +using CompanyManagment.App.Contracts.WorkingHoursTempItem; using CompanyManagment.App.Contracts.Workshop; +using CompanyManagment.App.Contracts.WorkshopPlan; using CompanyManagment.App.Contracts.YearlySalary; using CompanyManagment.App.Contracts.YearlySalaryItems; using CompanyManagment.App.Contracts.YearlySalaryTitles; +using CompanyManagment.App.Contracts.Zone; using CompanyManagment.Application; using CompanyManagment.EFCore; +using CompanyManagment.EFCore._common; +using CompanyManagment.EFCore.Repository; using CompanyManagment.EFCore.Repository; using File.EfCore.Repository; using Microsoft.EntityFrameworkCore; @@ -239,6 +376,8 @@ using CompanyManagement.Infrastructure.Mongo.CameraBugReportRepo; using CameraBugReportRepository = CompanyManagement.Infrastructure.Mongo.CameraBugReportRepo.CameraBugReportRepository; using Company.Domain._common; using CompanyManagment.EFCore._common; +using CompanyManagment.EFCore.Services; +using Shared.Contracts.Holidays; namespace PersonalContractingParty.Config; @@ -246,6 +385,12 @@ public class PersonalBootstrapper { public static void Configure(IServiceCollection services, string connectionString) { + + #region Services + + services.AddTransient(); + + #endregion //----Task-Manager-Project--------------------------------- //services.AddTransient(); diff --git a/PersonalContractingParty.Config/PersonalContractingParty.Config.csproj b/PersonalContractingParty.Config/PersonalContractingParty.Config.csproj index 3e55f945..ae515e3a 100644 --- a/PersonalContractingParty.Config/PersonalContractingParty.Config.csproj +++ b/PersonalContractingParty.Config/PersonalContractingParty.Config.csproj @@ -1,11 +1,11 @@ - net8.0 + net10.0 - + diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/DomainEventHandlers/CustomerRegisteredHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/DomainEventHandlers/CustomerRegisteredHandler.cs new file mode 100644 index 00000000..778f3104 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/DomainEventHandlers/CustomerRegisteredHandler.cs @@ -0,0 +1,33 @@ +using MediatR; +using Microsoft.Extensions.Logging; +using GozareshgirProgramManager.Domain.CustomerAgg.Events; +using GozareshgirProgramManager.Application._Common.Models; + +namespace GozareshgirProgramManager.Application.DomainEventHandlers; + +public class CustomerRegisteredHandler : INotificationHandler> +{ + private readonly ILogger _logger; + + public CustomerRegisteredHandler(ILogger logger) + { + _logger = logger; + } + + public Task Handle(DomainEventNotification notification, CancellationToken cancellationToken) + { + var domainEvent = notification.DomainEvent; + + _logger.LogInformation( + "Customer registered: {CustomerId}, Name: {Name}, Email: {Email}", + domainEvent.CustomerId, + domainEvent.Name, + domainEvent.Email); + + + // اینجا می‌توانید email ارسال کنید یا کارهای دیگر انجام دهید + + return Task.CompletedTask; + } +} + diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/DomainEventHandlers/ProjectSection/TaskSectionAddedHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/DomainEventHandlers/ProjectSection/TaskSectionAddedHandler.cs new file mode 100644 index 00000000..a7538ef2 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/DomainEventHandlers/ProjectSection/TaskSectionAddedHandler.cs @@ -0,0 +1,23 @@ +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Application.Interfaces; +using GozareshgirProgramManager.Domain.ProjectAgg.Events; +using MediatR; +using Microsoft.Extensions.Logging; + +namespace GozareshgirProgramManager.Application.DomainEventHandlers.ProjectSection; + +public class ProjectSectionAddedHandler:INotificationHandler> +{ + private readonly ILogger _logger; + + public ProjectSectionAddedHandler(ILogger logger) + { + _logger = logger; + } + + public Task Handle(DomainEventNotification notification, CancellationToken cancellationToken) + { + + return Task.CompletedTask; + } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/DomainEventHandlers/ProjectSection/TaskSectionAssignedHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/DomainEventHandlers/ProjectSection/TaskSectionAssignedHandler.cs new file mode 100644 index 00000000..3f86a177 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/DomainEventHandlers/ProjectSection/TaskSectionAssignedHandler.cs @@ -0,0 +1,14 @@ +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Domain.ProjectAgg.Events; +using MediatR; + +namespace GozareshgirProgramManager.Application.DomainEventHandlers.ProjectSection; + +public class ProjectSectionAssignedHandler:INotificationHandler> +{ + public Task Handle(DomainEventNotification notification, CancellationToken cancellationToken) + { + var domainEvent = notification.DomainEvent; + return Task.CompletedTask; + } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/GozareshgirProgramManager.Application.csproj b/ProgramManager/src/Application/GozareshgirProgramManager.Application/GozareshgirProgramManager.Application.csproj new file mode 100644 index 00000000..41ec592d --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/GozareshgirProgramManager.Application.csproj @@ -0,0 +1,21 @@ + + + + net10.0 + enable + enable + + + + + + + + + + + + + + + diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Interfaces/IBoardNotificationService.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Interfaces/IBoardNotificationService.cs new file mode 100644 index 00000000..959e7fbf --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Interfaces/IBoardNotificationService.cs @@ -0,0 +1,6 @@ +namespace GozareshgirProgramManager.Application.Interfaces; + +public interface IBoardNotificationService +{ + Task SendProjectAssignedAsync(); +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Checkouts/Commands/CreateCheckout/CreateOrEditCheckoutCommandHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Checkouts/Commands/CreateCheckout/CreateOrEditCheckoutCommandHandler.cs new file mode 100644 index 00000000..3536ad0e --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Checkouts/Commands/CreateCheckout/CreateOrEditCheckoutCommandHandler.cs @@ -0,0 +1,267 @@ + +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Application.Modules.Checkouts.Queries.GetUserToGropCreate; +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.CheckoutAgg.Entities; +using GozareshgirProgramManager.Domain.CheckoutAgg.Enums; +using GozareshgirProgramManager.Domain.CheckoutAgg.Repositories; +using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; +using GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.DTOs; +using GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Enums; +using GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Repositories; +using GozareshgirProgramManager.Domain.UserAgg.Entities; +using MediatR; +using PersianTools.Core; +using System.Runtime.InteropServices; +using Microsoft.EntityFrameworkCore; +using Shared.Contracts.Holidays; + + +namespace GozareshgirProgramManager.Application.Modules.Checkouts.Commands.CreateCheckout; + +public class CreateOrEditCheckoutCommandHandler : IBaseCommandHandler +{ + private readonly ICheckoutRepository _checkoutRepository; + private readonly ISalaryPaymentSettingRepository _salaryPaymentSettingRepository; + private readonly ITaskSectionActivityRepository _taskSectionActivityRepository; + private readonly IUnitOfWork _unitOfWork; + private readonly IHolidayQueryService _holidayQueryService; + + + public CreateOrEditCheckoutCommandHandler(ICheckoutRepository checkoutRepository, IUnitOfWork unitOfWork, + ISalaryPaymentSettingRepository salaryPaymentSettingRepository, + ITaskSectionActivityRepository taskSectionActivityRepository, IHolidayQueryService holidayQueryService) + { + _checkoutRepository = checkoutRepository; + _unitOfWork = unitOfWork; + _salaryPaymentSettingRepository = salaryPaymentSettingRepository; + _taskSectionActivityRepository = taskSectionActivityRepository; + _holidayQueryService = holidayQueryService; + } + + public async Task Handle(CreateOrEditCheckoutCommand request, CancellationToken cancellationToken) + { + + switch (request.TypeOfCheckoutHandler) + { + case TypeOfCheckoutHandler.CreateInGroup: + return await Create(request.Year, request.Month, request.UserIdList); + break; + case TypeOfCheckoutHandler.SingleEdit: + case TypeOfCheckoutHandler.GroupEditing: + return await GroupOrSingleEditing(request.CheckoutIdList); + break; + + } + return OperationResult.Failure("نوع متد انتخاب نشده است"); + } + + /// + /// ایجاد گروهی فیش حقوقی + /// + /// + /// + /// + /// + public async Task Create(string? Year, string? Month, List? UserIdList) + { + if (string.IsNullOrWhiteSpace(Month)) + return OperationResult.Failure("ماه خالی است"); + if (string.IsNullOrWhiteSpace(Year)) + return OperationResult.Failure("سال خالی است"); + if (UserIdList == null) + return OperationResult.Failure("هیچ موردی برای ایجاد انتخاب نشده اشت"); + if (UserIdList.Count == 0) + return OperationResult.Failure("هیچ موردی برای ایجاد انتخاب نشده اشت"); + + var startDateGr = new DateTime(); + var EndDateGr = new DateTime(); + var persianStart = new PersianDateTime(); + + int year = 0; + int month = 0; + try + { + year = Convert.ToInt32(Year); + month = Convert.ToInt32(Month); + persianStart = new PersianDateTime(year, month, 1); + var startDateFa = $"{persianStart}"; + startDateGr = startDateFa.ToGeorgianDateTime(); + + var endDateFa = startDateFa.FindeEndOfMonth(); + + EndDateGr = endDateFa.ToGeorgianDateTime(); + + + } + catch (Exception) + { + + return OperationResult.Failure( + "خطا در ورود سال و ماه"); + } + + var totalDays = Convert.ToInt32((EndDateGr - startDateGr).TotalDays + 1); + + var getAllSettings = await _salaryPaymentSettingRepository.GetAllSettings(UserIdList); + var get = await _taskSectionActivityRepository.GetTotalTimeSpentPerUserInRangeAsync(startDateGr, EndDateGr); + + foreach (var user in getAllSettings) + { + var totalWorked = get.FirstOrDefault(x => x.UserId == user.UserId); + var totalTimeTotalMinutes = (int)totalWorked.TotalTime.TotalMinutes; + var res = await ComputeSalary(user.WorkingHoursListDto, totalTimeTotalMinutes, user.MonthlySalary, startDateGr, EndDateGr, user.HolidayWorking); + var createCheckout = new Checkout(startDateGr, EndDateGr, year, month, user.FullName, user.UserId, + res.MandatoryHours, totalTimeTotalMinutes, + totalDays, res.RemainingHours, user.MonthlySalary, res.MonthlySalaryPay, res.DeductionFromSalary); + await _checkoutRepository.CreateAsync(createCheckout); + } + + await _unitOfWork.SaveChangesAsync(); + + return OperationResult.Success(); + } + + /// + /// متد ویراش گروهی و تکی + /// + /// + /// + /// + /// + public async Task GroupOrSingleEditing(List? CheckoutIdList) + { + + if (CheckoutIdList == null) + return OperationResult.Failure("هیچ موردی برای ویرایش انتخاب نشده اشت"); + if (CheckoutIdList.Count == 0) + return OperationResult.Failure("هیچ موردی برای ویرایش انتخاب نشده اشت"); + + var checkouts = await _checkoutRepository.GetCheckoutListByIds(CheckoutIdList); + if (!checkouts.Any()) + return OperationResult.Failure("هیچ موردی برای ویرایش انتخاب نشده اشت"); + var UserIdList = checkouts.Select(x => x.UserId).ToList(); + var getAllSettings = await _salaryPaymentSettingRepository.GetAllSettings(UserIdList); + if (!getAllSettings.Any()) + return OperationResult.Failure("تنظیمات ساعت و حقوق یافت نشد"); + foreach (var checkoutId in CheckoutIdList) + { + var checkout = checkouts.FirstOrDefault(x => x.Id == checkoutId); + if (checkout == null) + return OperationResult.Failure("فیش مورد نظر یافت نشد"); + + var userSetting = getAllSettings.FirstOrDefault(x => x.UserId == checkout.UserId); + + var get = await _taskSectionActivityRepository.GetTotalTimeSpentByUserInRangeAsync(checkout.UserId, checkout.CheckoutStartDate, checkout.CheckoutEndDate); + + var totalTimeTotalMinutes = (int)get.TotalMinutes; + + var totalDays = Convert.ToInt32((checkout.CheckoutEndDate - checkout.CheckoutStartDate).TotalDays + 1); + var res = await ComputeSalary(userSetting.WorkingHoursListDto, totalTimeTotalMinutes, userSetting.MonthlySalary, checkout.CheckoutStartDate, checkout.CheckoutEndDate, userSetting.HolidayWorking); + checkout.Edit(res.MandatoryHours, totalTimeTotalMinutes, totalDays, res.RemainingHours, userSetting.MonthlySalary, res.MonthlySalaryPay, res.DeductionFromSalary); + + await _unitOfWork.SaveChangesAsync(); + } + + + + return OperationResult.Success(); + } + + /// + /// محاسبه حقوق + /// + /// + public async Task ComputeSalary(List workingHoursListDto, int totalHoursWorked, double monthlySalaryDefined, DateTime start, DateTime end, bool holidayWorking) + { + var startDate = start.ToFarsi(); + var startYear = Convert.ToInt32(startDate.Substring(0, 4)); + var startMonth = Convert.ToInt32(startDate.Substring(5, 2)); + var startDay = Convert.ToInt32(startDate.Substring(8, 2)); + var persianStart = new PersianDateTime(startYear, startMonth, startDay); + var endDate = end.ToFarsi(); + var endYear = Convert.ToInt32(endDate.Substring(0, 4)); + var endMonth = Convert.ToInt32(endDate.Substring(5, 2)); + var endDay = Convert.ToInt32(endDate.Substring(8, 2)); + var persianEnd = new PersianDateTime(endYear, endMonth, endDay); + var holidays = await _holidayQueryService.GetHolidaysInDates(start, end) ; + int mandatoryHours = 0; + for (var currentDay = persianStart; currentDay <= persianEnd; currentDay = currentDay.AddDays(1)) + { + var currentDayOfWeek = new DNTPersianUtils.Core.PersianDateTime(currentDay.Year, currentDay.Month, currentDay.Day); + var holidayDate = currentDay.ShamsiDate.ToGeorgianDateTime(); + var day = (PersianDayOfWeek)currentDayOfWeek.WeekDayNumber!; + var getDaySetting = workingHoursListDto.FirstOrDefault(x => x.PersianDayOfWeek == day); + if (getDaySetting != null) + { + if (!holidayWorking && holidays.Any(x => x.Holidaydate == holidayDate)) + { + + } + else + { + mandatoryHours += (int)getDaySetting.ShiftDuration.TotalMinutes; + Console.WriteLine((int)getDaySetting.ShiftDuration.TotalMinutes + " " + currentDay + " - " + day); + } + + + + } + + + + + } + //حقوق نهایی + var monthlySalaryPay = (totalHoursWorked * monthlySalaryDefined) / mandatoryHours; + // اگر اضافه کار داشت حقوق تعین شده به عنوان حقوق نهایی در نظر گرفته میشود + monthlySalaryPay = monthlySalaryPay > monthlySalaryDefined ? monthlySalaryDefined : monthlySalaryPay; + + //حقوق کسر شده + var deductionFromSalary = monthlySalaryDefined - monthlySalaryPay; + + //زمان باقی مانده + var remainingTime = totalHoursWorked - mandatoryHours; + + var computeResult = new ComputeResultDto + { + MandatoryHours = mandatoryHours, + MonthlySalaryPay = monthlySalaryPay, + DeductionFromSalary = deductionFromSalary, + RemainingHours = remainingTime + }; + Console.WriteLine(mandatoryHours); + return computeResult; + } + +} + + +public record CreateOrEditCheckoutCommand(TypeOfCheckoutHandler TypeOfCheckoutHandler, string? Year, string? Month, List? UserIdList, List? CheckoutIdList) : IBaseCommand; + +public record ComputeResultDto +{ + + /// + /// ساعات باقی مانده + /// کسر کار یا اضافه کار + /// + public int RemainingHours { get; set; } + + + /// + /// حقوق نهایی که به پرسنل داده می شود + /// + public double MonthlySalaryPay { get; set; } + + /// + /// کسر از حقوق + /// + public double DeductionFromSalary { get; set; } + + /// + /// ساعت موظفی + /// + public int MandatoryHours { get; set; } +} diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Checkouts/Queries/GetCheckoutList/GetCheckoutListQueryHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Checkouts/Queries/GetCheckoutList/GetCheckoutListQueryHandler.cs new file mode 100644 index 00000000..f2a93459 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Checkouts/Queries/GetCheckoutList/GetCheckoutListQueryHandler.cs @@ -0,0 +1,130 @@ +using GozareshgirProgramManager.Application._Common.Extensions; +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Application.Modules.Checkouts.Queries.GetUserToGropCreate; +using GozareshgirProgramManager.Domain._Common; +using Microsoft.EntityFrameworkCore; + +namespace GozareshgirProgramManager.Application.Modules.Checkouts.Queries.GetCheckoutList; + +public class GetCheckoutListQueryHandler : IBasePaginationQueryHandler +{ + private readonly IProgramManagerDbContext _programManagerDbContext; + + public GetCheckoutListQueryHandler(IProgramManagerDbContext programManagerDbContext) + { + _programManagerDbContext = programManagerDbContext; + } + + public async Task>> Handle(GetCheckoutListQuery request, CancellationToken cancellationToken) + { + var query = _programManagerDbContext.Checkouts.AsQueryable(); + + if (!string.IsNullOrWhiteSpace(request.Year)) + { + var year = Convert.ToInt32(request.Year); + query = query.Where(x => x.Year == year); + + } + + if (!string.IsNullOrWhiteSpace(request.Month)) + { + var month = Convert.ToInt32(request.Month); + query = query.Where(x => x.Month == month); + } + + if (!string.IsNullOrWhiteSpace(request.FullName)) + query = query.Where(x => x.FullName.Contains(request.FullName)); + + var res =await query.Select(x => new GetCheckoutListResponse() + { + CheckoutId = x.Id, + Year = x.Year, + Month = x.PersianMonthName, + FullName = x.FullName, + MandatoryHours = x.MandatoryHours, + TotalHoursWorked = x.TotalHoursWorked, + RemainingHours = x.RemainingHours, + MonthlySalaryDefined = x.MonthlySalaryDefined.ToMoney(), + DeductionFromSalary = x.DeductionFromSalary.ToMoney(), + MonthlySalaryPay = x.MonthlySalaryPay.ToMoney() + + + }).ApplyPagination(request.PageIndex,request.PageSize).ToListAsync(cancellationToken: cancellationToken); + + var response = new PaginationResult + { + List = res, + TotalCount = query.Count(), + }; + + return OperationResult>.Success(response); + } +} + +public record GetCheckoutListQuery(string? Month, string? Year, string? FullName) : PaginationRequest, IBasePaginationQuery; + +public record GetCheckoutListResponse +{ + /// + /// آی دی فیش حقوقی + /// + public Guid CheckoutId { get; set; } + + /// + /// سال + /// + public int Year { get; set; } + + /// + /// ماه + /// + public string Month { get; set; } + + /// + /// نام کامل پرسنل + /// + public string FullName { get; set; } + + + /// + /// ساعت موظفی + /// + public int MandatoryHours { get; set; } + + /// + /// مجموع ساعات کارکرد پرسنل + /// + public int TotalHoursWorked { get; set; } + + /// + /// ساعات باقی مانده + /// کسر کار یا اضافه کار + /// + public int RemainingHours { get; set; } + + + /// + /// حقوق ماهانه + /// تعیین شده + /// + public string MonthlySalaryDefined { get; set; } + + + /// + /// کسر از حقوق + /// + public string DeductionFromSalary { get; set; } + + + /// + /// حقوق نهایی که به پرسنل داده می شود + /// + public string MonthlySalaryPay { get; set; } +} + + + + + + diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Checkouts/Queries/GetUserToGropCreate/GetUserToGroupCreatingQueryHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Checkouts/Queries/GetUserToGropCreate/GetUserToGroupCreatingQueryHandler.cs new file mode 100644 index 00000000..1b04026a --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Checkouts/Queries/GetUserToGropCreate/GetUserToGroupCreatingQueryHandler.cs @@ -0,0 +1,174 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Application.Modules.SalaryPaymentSettings.Queries.GetUserListWhoHaveSettings; +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.CheckoutAgg.Enums; +using Microsoft.EntityFrameworkCore; +using PersianTools.Core; + +namespace GozareshgirProgramManager.Application.Modules.Checkouts.Queries.GetUserToGropCreate; + +/// +/// دریافت کاربران برای ایجاد گروهی فیش حقوقی با سال و ماه +/// +public class GetUserToGroupCreatingQueryHandler : IBaseQueryHandler +{ + private readonly IProgramManagerDbContext _context; + + public GetUserToGroupCreatingQueryHandler(IProgramManagerDbContext context) + { + _context = context; + } + + public async Task> Handle(GetUserToGroupCreatingQuery request, CancellationToken cancellationToken) + { + //سال و ماه انتخاب شده از فرانت + var selectedDate = new DateTime(); + try + { + int year = Convert.ToInt32(request.Year); + int month = Convert.ToInt32(request.Month); + selectedDate = ($"{new PersianDateTime(year,month,1)}").ToGeorgianDateTime(); + } + catch (Exception) + { + + return OperationResult.Failure( + "خطا در ورود سال و ماه"); + } + + //آخرین تاریخ مجاز برای ایجاد فیش + var lastMonth = ($"{DateTime.Now.ToFarsi().Substring(0, 8)}01").ToGeorgianDateTime().AddDays(-1); + + if (selectedDate > lastMonth) + return OperationResult.Failure( + "ایجاد فیش فقط برای ماه های گذشته امکان پذیر است"); + + + var lastMonthStart = lastMonth; + var lastMonthEnd = lastMonth; + + var query = + await (from u in _context.Users + + // LEFT JOIN + // تنظیمات حقوق + join s in _context.SalaryPaymentSettings + on u.Id equals s.UserId into sJoin + from s in sJoin.DefaultIfEmpty() + + // LEFT JOIN + //فیش + join ch in _context.Checkouts + .Where(x => x.CheckoutStartDate < lastMonthStart + && x.CheckoutEndDate >= lastMonthStart) + on u.Id equals ch.UserId into chJoin + from ch in chJoin.DefaultIfEmpty() + + group new { s, ch } by new { u.Id, u.FullName } into g + + select new GetUserWhoHaveSettingsAndCheckoutDto + { + UserId = g.Key.Id, + FullName = g.Key.FullName, + + HasSalarySettings = g.Any(x => x.s != null), + HasCheckout = g.Any(x => x.ch != null) + }) + .ToListAsync(cancellationToken); + + + + + + var responseList = query.Select(x => + { + + bool validToCreate = x.HasSalarySettings && !x.HasCheckout; + string message = "آماده تنظیم"; + CreateCheckoutStatus createCheckoutStatus = CreateCheckoutStatus.ReadyToCreate; + if (x.HasCheckout) + { + message = "موجود است"; + createCheckoutStatus = CreateCheckoutStatus.AlreadyCreated; + } + + + if (!x.HasSalarySettings) + { + message = "فاقد تنظیمات"; + createCheckoutStatus = CreateCheckoutStatus.NotSetSalaryPaymentSettings; + } + + + return new GetUserToGroupCreatingDto + { + UserId = x.UserId, + FullName = x.FullName, + IsValidToCreate = validToCreate, + StatusMessage = message, + CreateCheckoutStatus = createCheckoutStatus + + }; + + }).OrderByDescending(x=>x.IsValidToCreate).ToList(); + + var response = new GetUserToGroupCreatingResponse(responseList); + + return OperationResult.Success(response); + } +} + + +public record GetUserToGroupCreatingQuery(string Year, string Month) : IBaseQuery; + +public record GetUserToGroupCreatingResponse(List GetUserToGroupCreatingDtoList); + +public record GetUserToGroupCreatingDto +{ + /// + /// آی دی کاربر + /// + public long UserId { get; set; } + + /// + /// نام کامل پرسنل + /// + public string FullName { get; set; } + + + /// + /// پیام وضعیت ایجاد فیش + /// + public string StatusMessage { get; set; } + + /// + /// آیا مجاز به ایجاد فیش می باشد + /// + public bool IsValidToCreate { get; set; } + + public CreateCheckoutStatus CreateCheckoutStatus { get; set; } + +} + + +public record GetUserWhoHaveSettingsAndCheckoutDto +{ + /// + /// آی دی کاربر + /// + public long UserId { get; set; } + + /// + /// نام کامل پرسنل + /// + public string FullName { get; set; } + + /// + /// داشتن تنظیمات + /// + public bool HasSalarySettings { get; set; } + + + public bool HasCheckout { get; set; } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/AddPhaseToProject/AddPhaseToProjectCommand.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/AddPhaseToProject/AddPhaseToProjectCommand.cs new file mode 100644 index 00000000..427904e0 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/AddPhaseToProject/AddPhaseToProjectCommand.cs @@ -0,0 +1,13 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.AddPhaseToProject; + +/// +/// Command to add a phase to an existing project +/// +public record AddPhaseToProjectCommand( + Guid ProjectId, + string Name, + string? Description = null, + int OrderIndex = 0 +) : IBaseCommand; diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/AddPhaseToProject/AddPhaseToProjectCommandHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/AddPhaseToProject/AddPhaseToProjectCommandHandler.cs new file mode 100644 index 00000000..3eadac95 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/AddPhaseToProject/AddPhaseToProjectCommandHandler.cs @@ -0,0 +1,47 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; +using MediatR; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.AddPhaseToProject; + +public class AddPhaseToProjectCommandHandler : IRequestHandler +{ + private readonly IProjectRepository _projectRepository; + private readonly IUnitOfWork _unitOfWork; + + public AddPhaseToProjectCommandHandler( + IProjectRepository projectRepository, + IUnitOfWork unitOfWork) + { + _projectRepository = projectRepository; + _unitOfWork = unitOfWork; + } + + public async Task Handle(AddPhaseToProjectCommand request, CancellationToken cancellationToken) + { + try + { + // Get project + var project = await _projectRepository.GetByIdAsync(request.ProjectId); + if (project == null) + { + return OperationResult.NotFound("پروژه یافت نشد"); + } + + // Add phase + var phase = project.AddPhase(request.Name, request.Description); + phase.SetOrderIndex(request.OrderIndex); + + // Save changes + await _unitOfWork.SaveChangesAsync(cancellationToken); + + return OperationResult.Success(); + } + catch (Exception ex) + { + return OperationResult.Failure($"خطا در افزودن فاز: {ex.Message}"); + } + } +} diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/AddTaskToPhase/AddTaskToPhaseCommand.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/AddTaskToPhase/AddTaskToPhaseCommand.cs new file mode 100644 index 00000000..ba82f57c --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/AddTaskToPhase/AddTaskToPhaseCommand.cs @@ -0,0 +1,16 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Domain.ProjectAgg.Enums; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.AddTaskToPhase; + +/// +/// Command to add a task to an existing phase +/// +public record AddTaskToPhaseCommand( + Guid PhaseId, + string Name, + string? Description = null, + TaskPriority Priority = TaskPriority.Medium, + int OrderIndex = 0, + DateTime? DueDate = null +) : IBaseCommand; diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/AddTaskToPhase/AddTaskToPhaseCommandHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/AddTaskToPhase/AddTaskToPhaseCommandHandler.cs new file mode 100644 index 00000000..360811a7 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/AddTaskToPhase/AddTaskToPhaseCommandHandler.cs @@ -0,0 +1,53 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; +using MediatR; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.AddTaskToPhase; + +public class AddTaskToPhaseCommandHandler : IRequestHandler +{ + private readonly IProjectPhaseRepository _phaseRepository; + private readonly IUnitOfWork _unitOfWork; + + public AddTaskToPhaseCommandHandler( + IProjectPhaseRepository phaseRepository, + IUnitOfWork unitOfWork) + { + _phaseRepository = phaseRepository; + _unitOfWork = unitOfWork; + } + + public async Task Handle(AddTaskToPhaseCommand request, CancellationToken cancellationToken) + { + try + { + // Get phase + var phase = await _phaseRepository.GetByIdAsync(request.PhaseId); + if (phase == null) + { + return OperationResult.NotFound("فاز یافت نشد"); + } + + // Add task + var task = phase.AddTask(request.Name, request.Description); + task.SetPriority(request.Priority); + task.SetOrderIndex(request.OrderIndex); + + if (request.DueDate.HasValue) + { + task.SetDates(dueDate: request.DueDate); + } + + // Save changes + await _unitOfWork.SaveChangesAsync(cancellationToken); + + return OperationResult.Success(); + } + catch (Exception ex) + { + return OperationResult.Failure($"خطا در افزودن تسک: {ex.Message}"); + } + } +} diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/AssignProject/AssignProjectCommand.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/AssignProject/AssignProjectCommand.cs new file mode 100644 index 00000000..805ddb50 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/AssignProject/AssignProjectCommand.cs @@ -0,0 +1,18 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Domain.ProjectAgg.Enums; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.AssignProject; + +public class AssignProjectCommand:IBaseCommand +{ + public List Items { get; set; } + public Guid Id { get; set; } + public ProjectHierarchyLevel Level { get; set; } + public bool CascadeToChildren { get; set; } +} + +public class AssignProjectCommandItem +{ + public long UserId { get; set; } + public Guid SkillId { get; set; } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/AssignProject/AssignProjectCommandHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/AssignProject/AssignProjectCommandHandler.cs new file mode 100644 index 00000000..7dddf33e --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/AssignProject/AssignProjectCommandHandler.cs @@ -0,0 +1,274 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Enums; +using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; +using GozareshgirProgramManager.Domain.SkillAgg.Repositories; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.AssignProject; + +public class AssignProjectCommandHandler:IBaseCommandHandler +{ + private readonly IUnitOfWork _unitOfWork; + private readonly IProjectRepository _projectRepository; + private readonly IProjectPhaseRepository _projectPhaseRepository; + private readonly IProjectTaskRepository _projectTaskRepository; + private readonly ISkillRepository _skillRepository; + private readonly IPhaseSectionRepository _phaseSectionRepository; + private readonly IProjectSectionRepository _projectSectionRepository; + private readonly ITaskSectionRepository _taskSectionRepository; + + + public AssignProjectCommandHandler( + IProjectRepository projectRepository, + IProjectPhaseRepository projectPhaseRepository, + IProjectTaskRepository projectTaskRepository, + IUnitOfWork unitOfWork, + ISkillRepository skillRepository, + IPhaseSectionRepository phaseSectionRepository, + IProjectSectionRepository projectSectionRepository, + ITaskSectionRepository taskSectionRepository) + { + _projectRepository = projectRepository; + _projectPhaseRepository = projectPhaseRepository; + _projectTaskRepository = projectTaskRepository; + _unitOfWork = unitOfWork; + _skillRepository = skillRepository; + _phaseSectionRepository = phaseSectionRepository; + _projectSectionRepository = projectSectionRepository; + _taskSectionRepository = taskSectionRepository; + } + + public async Task Handle(AssignProjectCommand request, CancellationToken cancellationToken) + { + switch (request.Level) + { + case ProjectHierarchyLevel.Project: + return await AssignProject(request); + case ProjectHierarchyLevel.Phase: + return await AssignProjectPhase(request); + case ProjectHierarchyLevel.Task: + return await AssignProjectTask(request); + default: + return OperationResult.Failure("سطح پروژه نامعتبر است"); + } + } + + private async Task AssignProject(AssignProjectCommand request) + { + var project = await _projectRepository.GetWithFullHierarchyAsync(request.Id); + if (project is null) + { + return OperationResult.NotFound("پروژه یافت نشد"); + } + + // تخصیص در سطح پروژه + foreach (var item in request.Items) + { + var skill = await _skillRepository.GetByIdAsync(item.SkillId); + if (skill is null) + { + return OperationResult.NotFound($"مهارت با شناسه {item.SkillId} یافت نشد"); + } + + // بررسی و به‌روزرسانی یا اضافه کردن ProjectSection + var existingSection = project.ProjectSections.FirstOrDefault(s => s.SkillId == item.SkillId); + if (existingSection != null) + { + // اگر وجود داشت، فقط userId را به‌روزرسانی کن + existingSection.UpdateUser(item.UserId); + } + else + { + // اگر وجود نداشت، اضافه کن + var newSection = new ProjectSection(project.Id, item.UserId, item.SkillId); + await _projectSectionRepository.CreateAsync(newSection); + } + } + + // حالا برای تمام فازها و تسک‌ها cascade کن + foreach (var phase in project.Phases) + { + // اگر CascadeToChildren true است یا فاز override ندارد + if (request.CascadeToChildren || !phase.HasAssignmentOverride) + { + // برای phase هم باید section‌ها را به‌روزرسانی کنیم + foreach (var item in request.Items) + { + var existingSection = phase.PhaseSections.FirstOrDefault(s => s.SkillId == item.SkillId); + if (existingSection != null) + { + existingSection.Update(item.UserId, item.SkillId); + } + else + { + var newPhaseSection = new PhaseSection(phase.Id, item.UserId, item.SkillId); + await _phaseSectionRepository.CreateAsync(newPhaseSection); + } + } + + foreach (var task in phase.Tasks) + { + // اگر CascadeToChildren true است یا تسک override ندارد + if (request.CascadeToChildren || !task.HasAssignmentOverride) + { + foreach (var item in request.Items) + { + var section = task.Sections.FirstOrDefault(s => s.SkillId == item.SkillId); + if (section != null) + { + // استفاده از TransferToUser + if (section.CurrentAssignedUserId != item.UserId) + { + if (section.CurrentAssignedUserId > 0) + { + section.TransferToUser(section.CurrentAssignedUserId, item.UserId); + } + else + { + section.AssignToUser(item.UserId); + } + } + } + else + { + var newTaskSection = new TaskSection(task.Id, item.SkillId, item.UserId); + await _taskSectionRepository.CreateAsync(newTaskSection); + } + } + } + } + } + } + + await _unitOfWork.SaveChangesAsync(); + return OperationResult.Success(); + } + + private async Task AssignProjectPhase(AssignProjectCommand request) + { + var phase = await _projectPhaseRepository.GetWithTasksAsync(request.Id); + if (phase is null) + { + return OperationResult.NotFound("فاز پروژه یافت نشد"); + } + + // تخصیص در سطح فاز + foreach (var item in request.Items) + { + var skill = await _skillRepository.GetByIdAsync(item.SkillId); + if (skill is null) + { + return OperationResult.NotFound($"مهارت با شناسه {item.SkillId} یافت نشد"); + } + } + + // علامت‌گذاری که این فاز نسبت به parent متمایز است + phase.MarkAsOverridden(); + + // به‌روزرسانی یا اضافه کردن PhaseSection + foreach (var item in request.Items) + { + var existingSection = phase.PhaseSections.FirstOrDefault(s => s.SkillId == item.SkillId); + if (existingSection != null) + { + // اگر وجود داشت، فقط userId را به‌روزرسانی کن + existingSection.Update(item.UserId, item.SkillId); + } + else + { + // اگر وجود نداشت، اضافه کن + var newPhaseSection = new PhaseSection(phase.Id, item.UserId, item.SkillId); + await _phaseSectionRepository.CreateAsync(newPhaseSection); + } + } + + // cascade به تمام تسک‌ها + foreach (var task in phase.Tasks) + { + // اگر CascadeToChildren true است یا تسک override ندارد + if (request.CascadeToChildren || !task.HasAssignmentOverride) + { + foreach (var item in request.Items) + { + var section = task.Sections.FirstOrDefault(s => s.SkillId == item.SkillId); + if (section != null) + { + // استفاده از TransferToUser + if (section.CurrentAssignedUserId != item.UserId) + { + if (section.CurrentAssignedUserId > 0) + { + section.TransferToUser(section.CurrentAssignedUserId, item.UserId); + } + else + { + section.AssignToUser(item.UserId); + } + } + } + else + { + var newTaskSection = new TaskSection(task.Id, item.SkillId, item.UserId); + await _taskSectionRepository.CreateAsync(newTaskSection); + } + } + } + } + + await _unitOfWork.SaveChangesAsync(); + return OperationResult.Success(); + } + + private async Task AssignProjectTask(AssignProjectCommand request) + { + var task = await _projectTaskRepository.GetWithSectionsAsync(request.Id); + if (task is null) + { + return OperationResult.NotFound("تسک یافت نشد"); + } + + foreach (var item in request.Items) + { + var skill = await _skillRepository.GetByIdAsync(item.SkillId); + if (skill is null) + { + return OperationResult.NotFound($"مهارت با شناسه {item.SkillId} یافت نشد"); + } + } + + // علامت‌گذاری که این تسک نسبت به parent متمایز است + task.MarkAsOverridden(); + + // به‌روزرسانی یا اضافه کردن TaskSection + foreach (var item in request.Items) + { + var section = task.Sections.FirstOrDefault(s => s.SkillId == item.SkillId); + if (section != null) + { + // اگر وجود داشت، از TransferToUser استفاده کن + if (section.CurrentAssignedUserId != item.UserId) + { + if (section.CurrentAssignedUserId > 0) + { + section.TransferToUser(section.CurrentAssignedUserId, item.UserId); + } + else + { + section.AssignToUser(item.UserId); + } + } + } + else + { + // اگر وجود نداشت، اضافه کن + var newTaskSection = new TaskSection(task.Id, item.SkillId, item.UserId); + await _taskSectionRepository.CreateAsync(newTaskSection); + } + } + + await _unitOfWork.SaveChangesAsync(); + return OperationResult.Success(); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/AssignProject/AssignProjectCommandValidator.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/AssignProject/AssignProjectCommandValidator.cs new file mode 100644 index 00000000..6c1e80a8 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/AssignProject/AssignProjectCommandValidator.cs @@ -0,0 +1,39 @@ +using FluentValidation; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.AssignProject; + +public class AssignProjectCommandValidator : AbstractValidator +{ + public AssignProjectCommandValidator() + { + RuleFor(x => x.Id) + .NotEmpty() + .NotNull() + .WithMessage("شناسه پروژه نمیتواند خالی باشد"); + + RuleFor(x => x.CascadeToChildren) + .NotNull() + .WithMessage("مقدار CascadeToChildren نمیتواند خالی باشد"); + + RuleForEach(x => x.Items) + .SetValidator(new AssignProjectItemValidator()); + } +} + +public class AssignProjectItemValidator : AbstractValidator +{ + public AssignProjectItemValidator() + { + RuleFor(x => x.UserId) + .NotEmpty() + .NotNull() + .GreaterThan(0) + .WithMessage("شناسه کاربر نمیتواند خالی باشد"); + + + RuleFor(x => x.SkillId) + .NotEmpty() + .NotNull() + .WithMessage("شناسه مهارت نمیتواند خالی باشد"); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/ChangeStatusSection/ChangeStatusSectionCommandHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/ChangeStatusSection/ChangeStatusSectionCommandHandler.cs new file mode 100644 index 00000000..9e37cdc8 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/ChangeStatusSection/ChangeStatusSectionCommandHandler.cs @@ -0,0 +1,101 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain._Common.Exceptions; +using GozareshgirProgramManager.Domain.ProjectAgg.Enums; +using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.ChangeStatusSection; + +public record ChangeStatusSectionCommand(Guid SectionId, TaskSectionStatus Status) : IBaseCommand; + +public class ChangeStatusSectionCommandHandler : IBaseCommandHandler +{ + private readonly IUnitOfWork _unitOfWork; + private readonly ITaskSectionRepository _taskSectionRepository; + private readonly IAuthHelper _authHelper; + + public ChangeStatusSectionCommandHandler(ITaskSectionRepository taskSectionRepository, + IUnitOfWork unitOfWork, IAuthHelper authHelper) + { + _taskSectionRepository = taskSectionRepository; + _unitOfWork = unitOfWork; + _authHelper = authHelper; + } + + public async Task Handle(ChangeStatusSectionCommand request, CancellationToken cancellationToken) + { + // استفاده از متد مخصوص که Activities رو load می‌کنه + var section = await _taskSectionRepository.GetByIdWithActivitiesAsync(request.SectionId, cancellationToken); + if (section == null) + return OperationResult.NotFound("بخش مورد نظر یافت نشد"); + + if (section.Status == request.Status) + return OperationResult.Success(); + + long currentUser = _authHelper.GetCurrentUserId() + ?? throw new UnAuthorizedException("کاربر احراز هویت نشده است"); + + // Validate state transitions + var validationResult = ValidateStateTransition(section.Status, request.Status); + if (!validationResult.IsSuccess) + return validationResult; + + // Handle state machine logic + if (section.Status == TaskSectionStatus.InProgress) + { + // Coming FROM InProgress: Stop the active activity + section.StopWork(currentUser, request.Status); + } + else if (request.Status == TaskSectionStatus.InProgress) + { + // Going TO InProgress: Start work and create activity + section.StartWork(currentUser); + } + else + { + // All other transitions: Just update status + section.UpdateStatus(request.Status); + } + + await _unitOfWork.SaveChangesAsync(cancellationToken); + return OperationResult.Success(); + } + + /// + /// Validates state transitions based on business rules: + /// - ReadyToStart: شروع نشده - Initial state only, cannot return to it once left + /// - InProgress: درحال انجام - Can transition from ReadyToStart, can go to Incomplete or Completed + /// - Incomplete: نیمه کاره - Can come from InProgress or other states + /// - Completed: اتمام رسیده - Can come from InProgress or other states + /// + private OperationResult ValidateStateTransition(TaskSectionStatus currentStatus, TaskSectionStatus targetStatus) + { + // Cannot transition to ReadyToStart once the section has been started + if (targetStatus == TaskSectionStatus.ReadyToStart) + return OperationResult.ValidationError("بخش نمی‌تواند به وضعیت 'آماده برای شروع' تغییر کند"); + + // From ReadyToStart, can only go to InProgress + if (currentStatus == TaskSectionStatus.ReadyToStart && targetStatus != TaskSectionStatus.InProgress) + return OperationResult.ValidationError("از وضعیت 'آماده برای شروع' فقط می‌توان به 'درحال انجام' رفت"); + + // Valid transitions matrix + var validTransitions = new Dictionary> + { + { TaskSectionStatus.ReadyToStart, new List { TaskSectionStatus.InProgress } }, + { TaskSectionStatus.InProgress, new List { TaskSectionStatus.Incomplete, TaskSectionStatus.Completed } }, + { TaskSectionStatus.Incomplete, new List { TaskSectionStatus.InProgress, TaskSectionStatus.Completed } }, + { TaskSectionStatus.Completed, new List { TaskSectionStatus.InProgress, TaskSectionStatus.Incomplete } }, // Can return to InProgress or Incomplete + { TaskSectionStatus.NotAssigned, new List { TaskSectionStatus.InProgress, TaskSectionStatus.ReadyToStart } } + }; + + if (!validTransitions.TryGetValue(currentStatus, out var allowedTargets)) + return OperationResult.ValidationError($"وضعیت فعلی '{currentStatus}' نامعتبر است"); + + if (!allowedTargets.Contains(targetStatus)) + return OperationResult.ValidationError( + $"نمی‌توان از وضعیت '{currentStatus}' به '{targetStatus}' رفت"); + + return OperationResult.Success(); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/ChangeStatusSection/ChangeStatusSectionCommandValidator.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/ChangeStatusSection/ChangeStatusSectionCommandValidator.cs new file mode 100644 index 00000000..1de430c9 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/ChangeStatusSection/ChangeStatusSectionCommandValidator.cs @@ -0,0 +1,20 @@ +using FluentValidation; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.ChangeStatusSection; + +public class ChangeStatusSectionCommandValidator:AbstractValidator +{ + public ChangeStatusSectionCommandValidator() + { + RuleFor(c => c.SectionId) + .NotEmpty() + .NotNull() + .WithMessage("شناسه بخش نمی‌تواند خالی باشد"); + + RuleFor(c => c.Status) + .IsInEnum() + .NotEmpty() + .NotNull() + .WithMessage("وضعیت بخش نامعتبر است"); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/CreateProject/CreateProjectCommand.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/CreateProject/CreateProjectCommand.cs new file mode 100644 index 00000000..475e7aab --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/CreateProject/CreateProjectCommand.cs @@ -0,0 +1,7 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Domain.ProjectAgg.Enums; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.CreateProject; + +public record CreateProjectCommand(string Name,ProjectHierarchyLevel Level, + Guid? ParentId):IBaseCommand; \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/CreateProject/CreateProjectCommandHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/CreateProject/CreateProjectCommandHandler.cs new file mode 100644 index 00000000..1ba61509 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/CreateProject/CreateProjectCommandHandler.cs @@ -0,0 +1,82 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain._Common.Exceptions; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Enums; +using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.CreateProject; + +public class CreateProjectCommandHandler : IBaseCommandHandler +{ + private readonly IProjectRepository _projectRepository; + private readonly IProjectPhaseRepository _projectPhaseRepository; + private readonly IProjectTaskRepository _projectTaskRepository; + private readonly IUnitOfWork _unitOfWork; + + + public CreateProjectCommandHandler(IProjectRepository projectRepository, IUnitOfWork unitOfWork, IProjectTaskRepository projectTaskRepository, IProjectPhaseRepository projectPhaseRepository) + { + _projectRepository = projectRepository; + _unitOfWork = unitOfWork; + _projectTaskRepository = projectTaskRepository; + _projectPhaseRepository = projectPhaseRepository; + } + + public async Task Handle(CreateProjectCommand request, CancellationToken cancellationToken) + { + switch (request.Level) + { + case ProjectHierarchyLevel.Project: + await CreateProject(request); + break; + case ProjectHierarchyLevel.Phase: + await CreateProjectPhase(request); + break; + case ProjectHierarchyLevel.Task: + await CreateProjectTask(request); + break; + default: + return OperationResult.Failure("سطح پروژه نامعتبر است"); + } + + await _unitOfWork.SaveChangesAsync(cancellationToken); + return OperationResult.Success(); + } + + private async Task CreateProject(CreateProjectCommand request) + { + var project = new Project(request.Name); + await _projectRepository.CreateAsync(project); + } + + private async Task CreateProjectPhase(CreateProjectCommand request) + { + if (!request.ParentId.HasValue) + throw new BadRequestException("برای ایجاد فاز، شناسه پروژه الزامی است"); + + if(!_projectRepository.Exists(x=>x.Id == request.ParentId.Value)) + { + throw new BadRequestException("والد پروژه یافت نشد"); + } + + var projectPhase = new ProjectPhase(request.Name, request.ParentId.Value); + await _projectPhaseRepository.CreateAsync(projectPhase); + } + + private async Task CreateProjectTask(CreateProjectCommand request) + { + if (!request.ParentId.HasValue) + throw new BadRequestException("برای ایجاد تسک، شناسه فاز الزامی است"); + + if(!_projectPhaseRepository.Exists(x=>x.Id == request.ParentId.Value)) + { + throw new BadRequestException("والد پروژه یافت نشد"); + } + + var projectTask = new ProjectTask(request.Name, request.ParentId.Value); + await _projectTaskRepository.CreateAsync(projectTask); + } +} + \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/CreateProject/CreateProjectCommandValidator.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/CreateProject/CreateProjectCommandValidator.cs new file mode 100644 index 00000000..790e1f79 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/CreateProject/CreateProjectCommandValidator.cs @@ -0,0 +1,26 @@ +using FluentValidation; +using GozareshgirProgramManager.Domain.ProjectAgg.Enums; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.CreateProject; + +public class CreateProjectCommandValidator:AbstractValidator +{ + public CreateProjectCommandValidator() + { + RuleFor(x => x.Name) + .NotEmpty() + .NotNull() + .WithMessage("نام نمیتواند خالی باشد"); + + RuleFor(y => y.Level) + .NotNull() + .IsInEnum(); + When(x=>x.Level>ProjectHierarchyLevel.Project,()=> + { + RuleFor(x => x.ParentId) + .NotNull() + .NotEmpty() + .WithMessage("شناسه والد نمیتواند خالی باشد"); + }); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/CreateProjectWithHierarchy/CreateProjectWithHierarchyCommand.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/CreateProjectWithHierarchy/CreateProjectWithHierarchyCommand.cs new file mode 100644 index 00000000..385f516d --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/CreateProjectWithHierarchy/CreateProjectWithHierarchyCommand.cs @@ -0,0 +1,13 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.CreateProjectWithHierarchy; + +/// +/// Command to create a new project with the new hierarchy structure +/// +public record CreateProjectWithHierarchyCommand( + string Name, + string? Description = null, + DateTime? PlannedStartDate = null, + DateTime? PlannedEndDate = null +) : IBaseCommand; diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/CreateProjectWithHierarchy/CreateProjectWithHierarchyCommandHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/CreateProjectWithHierarchy/CreateProjectWithHierarchyCommandHandler.cs new file mode 100644 index 00000000..0a899924 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/CreateProjectWithHierarchy/CreateProjectWithHierarchyCommandHandler.cs @@ -0,0 +1,49 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; +using MediatR; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.CreateProjectWithHierarchy; + +public class CreateProjectWithHierarchyCommandHandler : IRequestHandler +{ + private readonly IProjectRepository _projectRepository; + private readonly IUnitOfWork _unitOfWork; + + public CreateProjectWithHierarchyCommandHandler( + IProjectRepository projectRepository, + IUnitOfWork unitOfWork) + { + _projectRepository = projectRepository; + _unitOfWork = unitOfWork; + } + + public async Task Handle(CreateProjectWithHierarchyCommand request, CancellationToken cancellationToken) + { + try + { + // Create new project + var project = new Project(request.Name, request.Description); + + // Set planned dates if provided + if (request.PlannedStartDate.HasValue || request.PlannedEndDate.HasValue) + { + project.SetPlannedDates(request.PlannedStartDate, request.PlannedEndDate); + } + + // Add to repository + await _projectRepository.CreateAsync(project); + + // Save changes + await _unitOfWork.SaveChangesAsync(cancellationToken); + + return OperationResult.Success(); + } + catch (Exception ex) + { + return OperationResult.Failure($"خطا در ایجاد پروژه: {ex.Message}"); + } + } +} diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/CreateProjectWithHierarchy/CreateProjectWithHierarchyCommandValidator.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/CreateProjectWithHierarchy/CreateProjectWithHierarchyCommandValidator.cs new file mode 100644 index 00000000..2e425dc9 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/CreateProjectWithHierarchy/CreateProjectWithHierarchyCommandValidator.cs @@ -0,0 +1,21 @@ +using FluentValidation; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.CreateProjectWithHierarchy; + +public class CreateProjectWithHierarchyCommandValidator : AbstractValidator +{ + public CreateProjectWithHierarchyCommandValidator() + { + RuleFor(x => x.Name) + .NotEmpty().WithMessage("نام پروژه نمی‌تواند خالی باشد") + .MaximumLength(200).WithMessage("نام پروژه نمی‌تواند بیش از 200 کاراکتر باشد"); + + RuleFor(x => x.Description) + .MaximumLength(1000).WithMessage("توضیحات نمی‌تواند بیش از 1000 کاراکتر باشد") + .When(x => !string.IsNullOrEmpty(x.Description)); + + RuleFor(x => x) + .Must(x => x.PlannedStartDate == null || x.PlannedEndDate == null || x.PlannedStartDate <= x.PlannedEndDate) + .WithMessage("تاریخ شروع برنامه‌ریزی شده نمی‌تواند بعد از تاریخ پایان برنامه‌ریزی شده باشد"); + } +} diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/DeleteProject/DeleteProjectCommandHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/DeleteProject/DeleteProjectCommandHandler.cs new file mode 100644 index 00000000..57677395 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/DeleteProject/DeleteProjectCommandHandler.cs @@ -0,0 +1,91 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain._Common.Exceptions; +using GozareshgirProgramManager.Domain.ProjectAgg.Enums; +using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.DeleteProject; + +public record DeleteProjectCommand(Guid Id,ProjectHierarchyLevel Level) : IBaseCommand; + +public class DeleteProjectCommandHandler : IBaseCommandHandler +{ + private readonly IUnitOfWork _unitOfWork; + private readonly IProjectRepository _projectRepository; + private readonly IProjectPhaseRepository _projectPhaseRepository; + private readonly IProjectTaskRepository _projectTaskRepository; + + public DeleteProjectCommandHandler( + IUnitOfWork unitOfWork, + IProjectRepository projectRepository, + IProjectPhaseRepository projectPhaseRepository, + IProjectTaskRepository projectTaskRepository) + { + _unitOfWork = unitOfWork; + _projectRepository = projectRepository; + _projectPhaseRepository = projectPhaseRepository; + _projectTaskRepository = projectTaskRepository; + } + + public async Task Handle(DeleteProjectCommand request, CancellationToken cancellationToken) + { + switch (request.Level) + { + case ProjectHierarchyLevel.Project: + await DeleteProject(request.Id); + break; + case ProjectHierarchyLevel.Phase: + await DeleteProjectPhase(request.Id); + break; + case ProjectHierarchyLevel.Task: + await DeleteProjectTask(request.Id); + break; + default: + return OperationResult.Failure("سطح پروژه نامعتبر است"); + } + + await _unitOfWork.SaveChangesAsync(cancellationToken); + return OperationResult.Success(); + } + + private async Task DeleteProject(Guid projectId) + { + var projectWithPhases = await _projectRepository.GetWithFullHierarchyAsync(projectId); + + if (projectWithPhases == null) + throw new NotFoundException("پروژه یافت نشد"); + + // بررسی اینکه پروژه فاز یا زیرمجموعه دارد یا نه + if (projectWithPhases.Phases != null && projectWithPhases.Phases.Any()) + throw new BadRequestException("نمی‌توان پروژه‌ای را حذف کرد که دارای فاز است. ابتدا تمام فازها را حذف کنید."); + + _projectRepository.Remove(projectWithPhases); + } + + private async Task DeleteProjectPhase(Guid phaseId) + { + var phase = await _projectPhaseRepository.GetByIdAsync(phaseId); + + if (phase == null) + throw new NotFoundException("فاز پروژه یافت نشد"); + + // بررسی اینکه فاز تسک یا زیرمجموعه دارد یا نه + var phaseWithTasks = await _projectPhaseRepository.GetWithTasksAsync(phaseId); + if (phaseWithTasks?.Tasks != null && phaseWithTasks.Tasks.Any()) + throw new InvalidOperationException("نمی‌توان فازی را حذف کرد که دارای تسک است. ابتدا تمام تسک‌ها را حذف کنید."); + + _projectPhaseRepository.Remove(phase); + } + + private async Task DeleteProjectTask(Guid taskId) + { + var task = await _projectTaskRepository.GetByIdAsync(taskId); + + if (task == null) + throw new NotFoundException("تسک یافت نشد"); + + // حذف خود تسک + _projectTaskRepository.Remove(task); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/DeleteProject/DeleteProjectCommandValidator.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/DeleteProject/DeleteProjectCommandValidator.cs new file mode 100644 index 00000000..47ae2eeb --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/DeleteProject/DeleteProjectCommandValidator.cs @@ -0,0 +1,19 @@ +using FluentValidation; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.DeleteProject; + +public class DeleteProjectCommandValidator:AbstractValidator +{ + public DeleteProjectCommandValidator() + { + RuleFor(x=>x.Id) + .NotEmpty() + .NotNull() + .WithMessage("شناسه پروژه نمی‌تواند خالی باشد."); + RuleFor(x=>x.Level) + .IsInEnum() + .NotNull() + .WithMessage("سطح حذف پروژه نامعتبر است."); + + } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/EditProject/EditProjectCommandHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/EditProject/EditProjectCommandHandler.cs new file mode 100644 index 00000000..af993664 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/EditProject/EditProjectCommandHandler.cs @@ -0,0 +1,80 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain._Common.Exceptions; +using GozareshgirProgramManager.Domain.ProjectAgg.Enums; +using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.EditProject; + +public record EditProjectCommand(string Name, Guid Id, ProjectHierarchyLevel Level): IBaseCommand; +public class EditProjectCommandHandler: IBaseCommandHandler +{ + private readonly IProjectRepository _projectRepository; + private readonly IProjectPhaseRepository _projectPhaseRepository; + private readonly IProjectTaskRepository _projectTaskRepository; + private readonly IUnitOfWork _unitOfWork; + + public EditProjectCommandHandler( + IProjectRepository projectRepository, + IProjectPhaseRepository projectPhaseRepository, + IProjectTaskRepository projectTaskRepository, + IUnitOfWork unitOfWork) + { + _projectRepository = projectRepository; + _projectPhaseRepository = projectPhaseRepository; + _projectTaskRepository = projectTaskRepository; + _unitOfWork = unitOfWork; + } + + public async Task Handle(EditProjectCommand request, CancellationToken cancellationToken) + { + switch (request.Level) + { + case ProjectHierarchyLevel.Project: + await EditProject(request); + break; + case ProjectHierarchyLevel.Phase: + await EditProjectPhase(request); + break; + case ProjectHierarchyLevel.Task: + await EditProjectTask(request); + break; + default: + return OperationResult.Failure("سطح پروژه نامعتبر است"); + } + + await _unitOfWork.SaveChangesAsync(cancellationToken); + return OperationResult.Success(); + } + + private async Task EditProject(EditProjectCommand request) + { + var project = await _projectRepository.GetByIdAsync(request.Id); + + if (project == null) + throw new NotFoundException("پروژه یافت نشد"); + + project.UpdateName(request.Name); + } + + private async Task EditProjectPhase(EditProjectCommand request) + { + var phase = await _projectPhaseRepository.GetByIdAsync(request.Id); + + if (phase == null) + throw new NotFoundException("فاز پروژه یافت نشد"); + + phase.UpdateName(request.Name); + } + + private async Task EditProjectTask(EditProjectCommand request) + { + var task = await _projectTaskRepository.GetByIdAsync(request.Id); + + if (task == null) + throw new NotFoundException("تسک یافت نشد"); + + task.UpdateName(request.Name); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/EditProject/EditProjectCommandValidator.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/EditProject/EditProjectCommandValidator.cs new file mode 100644 index 00000000..4c50a3b1 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/EditProject/EditProjectCommandValidator.cs @@ -0,0 +1,18 @@ +using FluentValidation; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.EditProject; + +public class EditProjectCommandValidator:AbstractValidator +{ + public EditProjectCommandValidator() + { + RuleFor(x => x.Name) + .NotEmpty() + .WithMessage("نام پروژه نمی‌تواند خالی باشد."); + + RuleFor(x=>x.Id) + .NotEmpty() + .NotNull().WithMessage("شناسه پروژه نمی‌تواند خالی باشد."); + + } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/SetTimeProject/SetTimeProjectCommand.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/SetTimeProject/SetTimeProjectCommand.cs new file mode 100644 index 00000000..230754b5 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/SetTimeProject/SetTimeProjectCommand.cs @@ -0,0 +1,13 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application.Modules.Projects.DTOs; +using GozareshgirProgramManager.Domain.ProjectAgg.Enums; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.SetTimeProject; + +public record SetTimeProjectCommand(List SectionItems, Guid Id, ProjectHierarchyLevel Level):IBaseCommand; + +public class SetTimeSectionTime +{ + public string Description { get; set; } + public int Hours { get; set; } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/SetTimeProject/SetTimeProjectCommandHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/SetTimeProject/SetTimeProjectCommandHandler.cs new file mode 100644 index 00000000..3b1a7b1f --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/SetTimeProject/SetTimeProjectCommandHandler.cs @@ -0,0 +1,164 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Application.Modules.Projects.DTOs; +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Enums; +using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.SetTimeProject; + +public class SetTimeProjectCommandHandler:IBaseCommandHandler +{ + private readonly IProjectRepository _projectRepository; + private readonly IProjectPhaseRepository _projectPhaseRepository; + private readonly IProjectTaskRepository _projectTaskRepository; + private readonly IUnitOfWork _unitOfWork; + private readonly IAuthHelper _authHelper; + private long? _userId; + + + public SetTimeProjectCommandHandler( + IProjectRepository projectRepository, + IProjectPhaseRepository projectPhaseRepository, + IProjectTaskRepository projectTaskRepository, + IUnitOfWork unitOfWork, IAuthHelper authHelper) + { + _projectRepository = projectRepository; + _projectPhaseRepository = projectPhaseRepository; + _projectTaskRepository = projectTaskRepository; + _unitOfWork = unitOfWork; + _authHelper = authHelper; + _userId = authHelper.GetCurrentUserId(); + } + + public async Task Handle(SetTimeProjectCommand request, CancellationToken cancellationToken) + { + switch (request.Level) + { + case ProjectHierarchyLevel.Task: + return await SetTimeForProjectTask(request, cancellationToken); + default: + return OperationResult.Failure("سطح پروژه نامعتبر است"); + + } + } + + private async Task SetTimeForProject(SetTimeProjectCommand request, CancellationToken cancellationToken) + { + var project = await _projectRepository.GetWithFullHierarchyAsync(request.Id); + if (project == null) + { + return OperationResult.NotFound("پروژه یافت نشد"); + return OperationResult.NotFound("���� ���� ���"); + } + + long? addedByUserId = _userId; + + // تنظیم زمان برای تمام sections در تمام فازها و تسک‌های پروژه + foreach (var phase in project.Phases) + { + foreach (var task in phase.Tasks) + { + foreach (var section in task.Sections) + { + var sectionItem = request.SectionItems.FirstOrDefault(si => si.SectionId == section.Id); + if (sectionItem != null) + { + SetSectionTime(section, sectionItem, addedByUserId); + } + } + } + } + + await _unitOfWork.SaveChangesAsync(cancellationToken); + return OperationResult.Success(); + } + + private async Task SetTimeForProjectPhase(SetTimeProjectCommand request, CancellationToken cancellationToken) + { + var phase = await _projectPhaseRepository.GetWithTasksAsync(request.Id); + if (phase == null) + { + return OperationResult.NotFound("فاز پروژه یافت نشد"); + return OperationResult.NotFound("��� ���� ���� ���"); + } + + long? addedByUserId = _userId; + + // تنظیم زمان برای تمام sections در تمام تسک‌های این فاز + foreach (var task in phase.Tasks) + { + foreach (var section in task.Sections) + { + var sectionItem = request.SectionItems.FirstOrDefault(si => si.SectionId == section.Id); + if (sectionItem != null) + { + SetSectionTime(section, sectionItem, addedByUserId); + } + } + } + + await _unitOfWork.SaveChangesAsync(cancellationToken); + return OperationResult.Success(); + } + + private async Task SetTimeForProjectTask(SetTimeProjectCommand request, CancellationToken cancellationToken) + { + var task = await _projectTaskRepository.GetWithSectionsAsync(request.Id); + if (task == null) + { + return OperationResult.NotFound("تسک یافت نشد"); + return OperationResult.NotFound("�Ә ���� ���"); + } + + long? addedByUserId = _userId; + + // تنظیم زمان مستقیماً برای sections این تسک + foreach (var section in task.Sections) + { + var sectionItem = request.SectionItems.FirstOrDefault(si => si.SectionId == section.Id); + if (sectionItem != null) + { + SetSectionTime(section, sectionItem, addedByUserId); + } + } + + await _unitOfWork.SaveChangesAsync(cancellationToken); + return OperationResult.Success(); + } + + private void SetSectionTime(TaskSection section, SetTimeProjectSectionItem sectionItem, long? addedByUserId) + { + var initData = sectionItem.InitData; + var initialTime = TimeSpan.FromHours(initData.Hours); + + // تنظیم زمان اولیه + section.UpdateInitialEstimatedHours(initialTime, initData.Description); + + section.ClearAdditionalTimes(); + // افزودن زمان‌های اضافی + foreach (var additionalTime in sectionItem.AdditionalTime) + { + var additionalTimeSpan = TimeSpan.FromHours(additionalTime.Hours); + section.AddAdditionalTime(additionalTimeSpan, additionalTime.Description, addedByUserId); + } + } + + // private void SetSectionTime(ProjectSection section, SetTimeProjectSectionItem sectionItem, long? addedByUserId) + // { + // var initData = sectionItem.InitData; + // var initialTime = TimeSpan.FromHours(initData.Hours); + // + // // تنظیم زمان اولیه + // section.UpdateInitialEstimatedHours(initialTime, initData.Description); + // + // section.ClearAdditionalTimes(); + // // افزودن زمان‌های اضافی + // foreach (var additionalTime in sectionItem.AdditionalTime) + // { + // var additionalTimeSpan = TimeSpan.FromHours(additionalTime.Hours); + // section.AddAdditionalTime(additionalTimeSpan, additionalTime.Description, addedByUserId); + // } + // } +} diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/SetTimeProject/SetTimeProjectCommandValidator.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/SetTimeProject/SetTimeProjectCommandValidator.cs new file mode 100644 index 00000000..7fb182b7 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/SetTimeProject/SetTimeProjectCommandValidator.cs @@ -0,0 +1,50 @@ +using FluentValidation; +using GozareshgirProgramManager.Application.Modules.Projects.DTOs; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.SetTimeProject; + +public class SetTimeProjectCommandValidator:AbstractValidator +{ + public SetTimeProjectCommandValidator() + { + RuleFor(x=>x.Id) + .NotEmpty() + .NotNull() + .WithMessage("شناسه پروژه نمی‌تواند خالی باشد."); + + RuleForEach(x => x.SectionItems) + .SetValidator(command => new SetTimeProjectSectionItemValidator()); + + } +} +public class SetTimeProjectSectionItemValidator:AbstractValidator +{ + public SetTimeProjectSectionItemValidator() + { + RuleFor(x=>x.SectionId) + .NotEmpty() + .NotNull() + .WithMessage("شناسه بخش نمی‌تواند خالی باشد."); + + RuleFor(x=>x.InitData) + .SetValidator(new TimeDataValidator()); + + RuleForEach(x=>x.AdditionalTime) + .SetValidator(new TimeDataValidator()); + } +} + +public class TimeDataValidator : AbstractValidator +{ + public TimeDataValidator() + { + RuleFor(x => x.Hours) + .GreaterThanOrEqualTo(0) + .WithMessage("ساعت نمی‌تواند منفی باشد."); + + RuleFor(x=>x.Description) + .MaximumLength(500) + .WithMessage("توضیحات نمی‌تواند بیشتر از 500 کاراکتر باشد."); + + } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/TransferSection/TransferSectionCommand.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/TransferSection/TransferSectionCommand.cs new file mode 100644 index 00000000..b32f49a2 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/TransferSection/TransferSectionCommand.cs @@ -0,0 +1,12 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.TransferSection; + +public record TransferSectionCommand : IBaseCommand +{ + public Guid SectionId { get; set; } + public long FromUserId { get; set; } + public long ToUserId { get; set; } + public string? Notes { get; set; } +} + diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/TransferSection/TransferSectionCommandHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/TransferSection/TransferSectionCommandHandler.cs new file mode 100644 index 00000000..4f27773a --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/TransferSection/TransferSectionCommandHandler.cs @@ -0,0 +1,69 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; +using GozareshgirProgramManager.Domain.UserAgg.Repositories; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.TransferSection; + +public class TransferSectionCommandHandler : IBaseCommandHandler +{ + private readonly IUnitOfWork _unitOfWork; + private readonly ITaskSectionRepository _taskSectionRepository; + private readonly IUserRepository _userRepository; + + public TransferSectionCommandHandler( + ITaskSectionRepository taskSectionRepository, + IUserRepository userRepository, + IUnitOfWork unitOfWork) + { + _taskSectionRepository = taskSectionRepository; + _userRepository = userRepository; + _unitOfWork = unitOfWork; + } + + public async Task Handle(TransferSectionCommand request, CancellationToken cancellationToken) + { + // دریافت section با activities + var section = await _taskSectionRepository.GetByIdWithActivitiesAsync(request.SectionId, cancellationToken); + if (section == null) + { + return OperationResult.NotFound("بخش پروژه یافت نشد"); + } + + // بررسی وجود کاربر مبدا + var fromUser = await _userRepository.GetByIdAsync(request.FromUserId); + if (fromUser == null) + { + return OperationResult.NotFound($"کاربر مبدا با شناسه {request.FromUserId} یافت نشد"); + } + + // بررسی وجود کاربر مقصد + var toUser = await _userRepository.GetByIdAsync(request.ToUserId); + if (toUser == null) + { + return OperationResult.NotFound($"کاربر مقصد با شناسه {request.ToUserId} یافت نشد"); + } + + // بررسی اینکه کاربر مبدا و مقصد یکسان نباشند + if (request.FromUserId == request.ToUserId) + { + return OperationResult.Failure("کاربر مبدا و مقصد نمی‌توانند یکسان باشند"); + } + + try + { + // انتقال به کاربر جدید + section.TransferToUser(request.FromUserId, request.ToUserId); + + await _unitOfWork.SaveChangesAsync(cancellationToken); + + return OperationResult.Success(); + } + catch (InvalidOperationException ex) + { + return OperationResult.Failure(ex.Message); + } + } +} + diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/TransferSection/TransferSectionCommandValidator.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/TransferSection/TransferSectionCommandValidator.cs new file mode 100644 index 00000000..e7b041f3 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Commands/TransferSection/TransferSectionCommandValidator.cs @@ -0,0 +1,28 @@ +using FluentValidation; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Commands.TransferSection; + +public class TransferSectionCommandValidator : AbstractValidator +{ + public TransferSectionCommandValidator() + { + RuleFor(x => x.SectionId) + .NotEmpty() + .WithMessage("شناسه بخش نمیتواند خالی باشد"); + + RuleFor(x => x.FromUserId) + .NotEmpty() + .GreaterThan(0) + .WithMessage("شناسه کاربر مبدا نمیتواند خالی یا صفر باشد"); + + RuleFor(x => x.ToUserId) + .NotEmpty() + .GreaterThan(0) + .WithMessage("شناسه کاربر مقصد نمیتواند خالی یا صفر باشد"); + + RuleFor(x => x) + .Must(x => x.FromUserId != x.ToUserId) + .WithMessage("کاربر مبدا و مقصد نمی‌توانند یکسان باشند"); + } +} + diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/DTOs/ProjectHierarchyDtos.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/DTOs/ProjectHierarchyDtos.cs new file mode 100644 index 00000000..3cbc8cec --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/DTOs/ProjectHierarchyDtos.cs @@ -0,0 +1,127 @@ +namespace GozareshgirProgramManager.Application.Modules.Projects.DTOs; + +/// +/// DTO for Project entity +/// +public class ProjectDto +{ + public Guid Id { get; set; } + public string Name { get; set; } = string.Empty; + public string? Description { get; set; } + public DateTime CreationDate { get; set; } + public DateTime? StartDate { get; set; } + public DateTime? EndDate { get; set; } + public DateTime? PlannedStartDate { get; set; } + public DateTime? PlannedEndDate { get; set; } + public string Status { get; set; } = string.Empty; + public TimeSpan? AllocatedTime { get; set; } + public bool HasTimeOverride { get; set; } + public bool HasAssignmentOverride { get; set; } + public TimeSpan TotalTimeSpent { get; set; } + public TimeSpan TotalEstimatedTime { get; set; } + + public List Phases { get; set; } = new(); +} + +/// +/// DTO for ProjectPhase entity +/// +public class ProjectPhaseDto +{ + public Guid Id { get; set; } + public string Name { get; set; } = string.Empty; + public string? Description { get; set; } + public DateTime CreationDate { get; set; } + public Guid ProjectId { get; set; } + public string Status { get; set; } = string.Empty; + public DateTime? StartDate { get; set; } + public DateTime? EndDate { get; set; } + public int OrderIndex { get; set; } + public TimeSpan? AllocatedTime { get; set; } + public bool HasTimeOverride { get; set; } + public bool HasAssignmentOverride { get; set; } + public TimeSpan TotalTimeSpent { get; set; } + public TimeSpan TotalEstimatedTime { get; set; } + + public List Tasks { get; set; } = new(); +} + +/// +/// DTO for ProjectTask entity +/// +public class ProjectTaskDto +{ + public Guid Id { get; set; } + public string Name { get; set; } = string.Empty; + public string? Description { get; set; } + public DateTime CreationDate { get; set; } + public Guid PhaseId { get; set; } + public string Status { get; set; } = string.Empty; + public string Priority { get; set; } = string.Empty; + public DateTime? StartDate { get; set; } + public DateTime? EndDate { get; set; } + public DateTime? DueDate { get; set; } + public int OrderIndex { get; set; } + public TimeSpan? AllocatedTime { get; set; } + public bool HasTimeOverride { get; set; } + public bool HasAssignmentOverride { get; set; } + public TimeSpan TotalTimeSpent { get; set; } + public TimeSpan TotalEstimatedTime { get; set; } + + public List Sections { get; set; } = new(); +} + +/// +/// DTO for TaskSection entity +/// +public class ProjectSectionDto +{ + public Guid Id { get; set; } + public Guid TaskId { get; set; } + public Guid SkillId { get; set; } + public string SkillName { get; set; } = string.Empty; + public TimeSpan InitialEstimatedHours { get; set; } + public string? InitialDescription { get; set; } + public string Status { get; set; } = string.Empty; + public long CurrentAssignedUserId { get; set; } + public string? CurrentAssignedUserName { get; set; } + public DateTime CreationDate { get; set; } + + public TimeSpan FinalEstimatedHours { get; set; } + public TimeSpan TotalTimeSpent { get; set; } + public bool IsCompleted { get; set; } + public bool IsInProgress { get; set; } + + public List Activities { get; set; } = new(); + public List AdditionalTimes { get; set; } = new(); +} + +/// +/// DTO for ProjectSectionActivity entity +/// +public class TaskSectionActivityDto +{ + public Guid Id { get; set; } + public Guid SectionId { get; set; } + public long UserId { get; set; } + public string? UserName { get; set; } + public DateTime StartDate { get; set; } + public DateTime? EndDate { get; set; } + public string? Notes { get; set; } + public string? EndNotes { get; set; } + public bool IsActive { get; set; } + public TimeSpan TimeSpent { get; set; } +} + +/// +/// DTO for ProjectSectionAdditionalTime entity +/// +public class TaskSectionAdditionalTimeDto +{ + public Guid Id { get; set; } + public TimeSpan Hours { get; set; } + public string? Reason { get; set; } + public long? AddedByUserId { get; set; } + public string? AddedByUserName { get; set; } + public DateTime AddedAt { get; set; } +} diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/DTOs/SetTimeProjectSectionItem.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/DTOs/SetTimeProjectSectionItem.cs new file mode 100644 index 00000000..04566e4e --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/DTOs/SetTimeProjectSectionItem.cs @@ -0,0 +1,10 @@ +using GozareshgirProgramManager.Application.Modules.Projects.Commands.SetTimeProject; + +namespace GozareshgirProgramManager.Application.Modules.Projects.DTOs; + +public class SetTimeProjectSectionItem +{ + public Guid SectionId { get; set; } + public SetTimeSectionTime InitData { get; set; } + public List AdditionalTime { get; set; } = []; +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Extensions/ProjectMappingExtensions.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Extensions/ProjectMappingExtensions.cs new file mode 100644 index 00000000..67ce006e --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Extensions/ProjectMappingExtensions.cs @@ -0,0 +1,258 @@ +using GozareshgirProgramManager.Application.Modules.Projects.DTOs; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Enums; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Extensions; + +/// +/// Mapping extensions for project hierarchy entities to DTOs +/// +public static class ProjectMappingExtensions +{ + #region Project Mappings + + public static ProjectDto ToDto(this Project project) + { + return new ProjectDto + { + Id = project.Id, + Name = project.Name, + Description = project.Description, + CreationDate = project.CreationDate, + StartDate = project.StartDate, + EndDate = project.EndDate, + PlannedStartDate = project.PlannedStartDate, + PlannedEndDate = project.PlannedEndDate, + Status = project.Status.ToString(), + HasAssignmentOverride = project.HasAssignmentOverride, + TotalTimeSpent = project.GetTotalTimeSpent(), + TotalEstimatedTime = project.GetTotalEstimatedTime(), + Phases = project.Phases.Select(p => p.ToDto()).ToList() + }; + } + + public static ProjectDto ToSummaryDto(this Project project) + { + return new ProjectDto + { + Id = project.Id, + Name = project.Name, + Description = project.Description, + CreationDate = project.CreationDate, + StartDate = project.StartDate, + EndDate = project.EndDate, + PlannedStartDate = project.PlannedStartDate, + PlannedEndDate = project.PlannedEndDate, + Status = project.Status.ToString(), + HasAssignmentOverride = project.HasAssignmentOverride, + TotalTimeSpent = project.GetTotalTimeSpent(), + TotalEstimatedTime = project.GetTotalEstimatedTime() + // No phases for summary + }; + } + + #endregion + + #region Phase Mappings + + public static ProjectPhaseDto ToDto(this ProjectPhase phase) + { + return new ProjectPhaseDto + { + Id = phase.Id, + Name = phase.Name, + Description = phase.Description, + CreationDate = phase.CreationDate, + ProjectId = phase.ProjectId, + Status = phase.Status.ToString(), + StartDate = phase.StartDate, + EndDate = phase.EndDate, + OrderIndex = phase.OrderIndex, + HasAssignmentOverride = phase.HasAssignmentOverride, + TotalTimeSpent = phase.GetTotalTimeSpent(), + TotalEstimatedTime = phase.GetTotalEstimatedTime(), + Tasks = phase.Tasks.Select(t => t.ToDto()).ToList() + }; + } + + public static ProjectPhaseDto ToSummaryDto(this ProjectPhase phase) + { + return new ProjectPhaseDto + { + Id = phase.Id, + Name = phase.Name, + Description = phase.Description, + CreationDate = phase.CreationDate, + ProjectId = phase.ProjectId, + Status = phase.Status.ToString(), + StartDate = phase.StartDate, + EndDate = phase.EndDate, + OrderIndex = phase.OrderIndex, + HasAssignmentOverride = phase.HasAssignmentOverride, + TotalTimeSpent = phase.GetTotalTimeSpent(), + TotalEstimatedTime = phase.GetTotalEstimatedTime() + // No tasks for summary + }; + } + + #endregion + + #region Task Mappings + + public static ProjectTaskDto ToDto(this ProjectTask task) + { + return new ProjectTaskDto + { + Id = task.Id, + Name = task.Name, + Description = task.Description, + CreationDate = task.CreationDate, + PhaseId = task.PhaseId, + Status = task.Status.ToString(), + Priority = task.Priority.ToString(), + StartDate = task.StartDate, + EndDate = task.EndDate, + DueDate = task.DueDate, + OrderIndex = task.OrderIndex, + AllocatedTime = task.AllocatedTime, + HasTimeOverride = task.HasTimeOverride, + HasAssignmentOverride = task.HasAssignmentOverride, + TotalTimeSpent = task.GetTotalTimeSpent(), + TotalEstimatedTime = task.GetTotalEstimatedTime(), + Sections = task.Sections.Select(s => s.ToDto()).ToList() + }; + } + + public static ProjectTaskDto ToSummaryDto(this ProjectTask task) + { + return new ProjectTaskDto + { + Id = task.Id, + Name = task.Name, + Description = task.Description, + CreationDate = task.CreationDate, + PhaseId = task.PhaseId, + Status = task.Status.ToString(), + Priority = task.Priority.ToString(), + StartDate = task.StartDate, + EndDate = task.EndDate, + DueDate = task.DueDate, + OrderIndex = task.OrderIndex, + AllocatedTime = task.AllocatedTime, + HasTimeOverride = task.HasTimeOverride, + HasAssignmentOverride = task.HasAssignmentOverride, + TotalTimeSpent = task.GetTotalTimeSpent(), + TotalEstimatedTime = task.GetTotalEstimatedTime() + // No sections for summary + }; + } + + #endregion + + #region Section Mappings + + public static ProjectSectionDto ToDto(this TaskSection section) + { + return new ProjectSectionDto + { + Id = section.Id, + TaskId = section.TaskId, + SkillId = section.SkillId, + SkillName = section.Skill?.Name ?? string.Empty, + InitialEstimatedHours = section.InitialEstimatedHours, + InitialDescription = section.InitialDescription, + Status = section.Status.ToString(), + CurrentAssignedUserId = section.CurrentAssignedUserId, + CreationDate = section.CreationDate, + FinalEstimatedHours = section.FinalEstimatedHours, + TotalTimeSpent = section.GetTotalTimeSpent(), + IsCompleted = section.IsCompleted(), + IsInProgress = section.IsInProgress(), + Activities = section.Activities.Select(a => a.ToDto()).ToList(), + AdditionalTimes = section.AdditionalTimes.Select(at => at.ToDto()).ToList() + }; + } + + public static ProjectSectionDto ToSummaryDto(this TaskSection section) + { + return new ProjectSectionDto + { + Id = section.Id, + TaskId = section.TaskId, + SkillId = section.SkillId, + SkillName = section.Skill?.Name ?? string.Empty, + InitialEstimatedHours = section.InitialEstimatedHours, + InitialDescription = section.InitialDescription, + Status = section.Status.ToString(), + CurrentAssignedUserId = section.CurrentAssignedUserId, + CreationDate = section.CreationDate, + FinalEstimatedHours = section.FinalEstimatedHours, + TotalTimeSpent = section.GetTotalTimeSpent(), + IsCompleted = section.IsCompleted(), + IsInProgress = section.IsInProgress() + // No activities or additional times for summary + }; + } + + #endregion + + #region Activity Mappings + + public static TaskSectionActivityDto ToDto(this TaskSectionActivity activity) + { + return new TaskSectionActivityDto + { + Id = activity.Id, + SectionId = activity.SectionId, + UserId = activity.UserId, + StartDate = activity.StartDate, + EndDate = activity.EndDate, + Notes = activity.Notes, + EndNotes = activity.EndNotes, + IsActive = activity.IsActive, + TimeSpent = activity.GetTimeSpent() + }; + } + + #endregion + + #region Additional Time Mappings + + public static TaskSectionAdditionalTimeDto ToDto(this TaskSectionAdditionalTime additionalTime) + { + return new TaskSectionAdditionalTimeDto + { + Id = additionalTime.Id, + Hours = additionalTime.Hours, + Reason = additionalTime.Reason, + AddedByUserId = additionalTime.AddedByUserId, + AddedAt = additionalTime.AddedAt + }; + } + + #endregion + + #region Collection Mappings + + public static List ToSummaryDtos(this IEnumerable projects) + { + return projects.Select(p => p.ToSummaryDto()).ToList(); + } + + public static List ToSummaryDtos(this IEnumerable phases) + { + return phases.Select(p => p.ToSummaryDto()).ToList(); + } + + public static List ToSummaryDtos(this IEnumerable tasks) + { + return tasks.Select(t => t.ToSummaryDto()).ToList(); + } + + public static List ToSummaryDtos(this IEnumerable sections) + { + return sections.Select(s => s.ToSummaryDto()).ToList(); + } + + #endregion +} diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/GetProjectAssignDetails/GetProjectAssignDetailsQueryHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/GetProjectAssignDetails/GetProjectAssignDetailsQueryHandler.cs new file mode 100644 index 00000000..7932fd4c --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/GetProjectAssignDetails/GetProjectAssignDetailsQueryHandler.cs @@ -0,0 +1,122 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Domain.ProjectAgg.Enums; +using Microsoft.EntityFrameworkCore; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Queries.GetProjectAssignDetails; + +public record GetProjectAssignDetailsResponse(List Items); + +public record GetProjectAssignSectionDetails(string Skill,Guid SkillId,Guid? SectionId,long UserId); + +public record GetProjectAssignDetailsQuery(Guid Id,ProjectHierarchyLevel Level) : IBaseQuery; + +public class GetProjectAssignDetailsQueryHandler:IBaseQueryHandler +{ + private readonly IProgramManagerDbContext _dbContext; + + public GetProjectAssignDetailsQueryHandler(IProgramManagerDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task> Handle(GetProjectAssignDetailsQuery request, CancellationToken cancellationToken) + { + switch (request.Level) + { + case ProjectHierarchyLevel.Project: + return await GetProjectAssignDetails(request.Id, cancellationToken); + case ProjectHierarchyLevel.Phase: + return await GetPhaseAssignDetails(request.Id, cancellationToken); + case ProjectHierarchyLevel.Task: + return await GetTaskAssignDetails(request.Id, cancellationToken); + default: + return OperationResult.Failure("سطح پروژه نامعتبر است"); + } + } + + private async Task> GetProjectAssignDetails(Guid projectId, CancellationToken cancellationToken) + { + // گرفتن تمام فازهای پروژه + + var skills = _dbContext.Skills.ToList(); + var sectionsData =await _dbContext.ProjectSections + .Where(p => p.ProjectId == projectId).ToListAsync(cancellationToken); + + if (skills.Count == 0) + { + return OperationResult.Success(new GetProjectAssignDetailsResponse(new List())); + } + var sections = skills.Select(x=> + { + var section = sectionsData.FirstOrDefault(s => s.SkillId == x.Id); + + return new GetProjectAssignSectionDetails( + x.Name, + x.Id, + section?.Id, + section?.UserId ?? 0 + ); + + }).ToList(); + var response = new GetProjectAssignDetailsResponse(sections); + return OperationResult.Success(response); + } + + private async Task> GetPhaseAssignDetails(Guid phaseId, CancellationToken cancellationToken) + { + var skills = _dbContext.Skills.ToList(); + + var sectionsData =await _dbContext.PhaseSections + .Where(p => p.PhaseId == phaseId) + .ToListAsync(cancellationToken: cancellationToken); + + if (skills.Count == 0) + { + return OperationResult.Success(new GetProjectAssignDetailsResponse(new List())); + } + + var sections = skills.Select(x=> + { + var section = sectionsData.FirstOrDefault(s => s.SkillId == x.Id); + + return new GetProjectAssignSectionDetails( + x.Name, + x.Id, + section?.Id, + section?.UserId ?? 0 + ); + + }).ToList(); + + var response = new GetProjectAssignDetailsResponse(sections); + return OperationResult.Success(response); + } + + private async Task> GetTaskAssignDetails(Guid taskId, CancellationToken cancellationToken) + { + var skills = _dbContext.Skills.ToList(); + var sectionsData =await _dbContext.TaskSections + .Where(p => p.TaskId == taskId).ToListAsync(cancellationToken); + + if (skills.Count == 0) + { + return OperationResult.Success(new GetProjectAssignDetailsResponse(new List())); + } + var sections = skills.Select(x=> + { + var section = sectionsData.FirstOrDefault(s => s.SkillId == x.Id); + + return new GetProjectAssignSectionDetails( + x.Name, + x.Id, + section?.Id, + section?.OriginalAssignedUserId ?? 0 + ); + + }).ToList(); + + var response = new GetProjectAssignDetailsResponse(sections); + return OperationResult.Success(response); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/GetProjectsList/GetProjectListDto.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/GetProjectsList/GetProjectListDto.cs new file mode 100644 index 00000000..74a58946 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/GetProjectsList/GetProjectListDto.cs @@ -0,0 +1,18 @@ +using GozareshgirProgramManager.Domain.ProjectAgg.Enums; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Queries.GetProjectsList; +public record GetProjectListDto +{ + public Guid Id { get; init; } + public string Name { get; init; } = string.Empty; + public int Percentage { get; init; } + public ProjectHierarchyLevel Level { get; init; } + public Guid? ParentId { get; init; } + public bool HasFront { get; set; } + public bool HasBackend { get; set; } + public bool HasDesign { get; set; } + +} + + + diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/GetProjectsList/GetProjectsListQuery.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/GetProjectsList/GetProjectsListQuery.cs new file mode 100644 index 00000000..472af143 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/GetProjectsList/GetProjectsListQuery.cs @@ -0,0 +1,8 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Domain.ProjectAgg.Enums; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Queries.GetProjectsList; + +public record GetProjectsListQuery(ProjectHierarchyLevel HierarchyLevel, + Guid? ParentId) : IBaseQuery; + diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/GetProjectsList/GetProjectsListQueryHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/GetProjectsList/GetProjectsListQueryHandler.cs new file mode 100644 index 00000000..523943aa --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/GetProjectsList/GetProjectsListQueryHandler.cs @@ -0,0 +1,303 @@ +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.Queries.GetProjectsList; + +public class GetProjectsListQueryHandler : IBaseQueryHandler +{ + private readonly IProgramManagerDbContext _context; + + public GetProjectsListQueryHandler(IProgramManagerDbContext context) + { + _context = context; + } + + public async Task> Handle(GetProjectsListQuery request, CancellationToken cancellationToken) + { + List projects; + + switch (request.HierarchyLevel) + { + case ProjectHierarchyLevel.Project: + projects = await GetProjects(request.ParentId, cancellationToken); + break; + case ProjectHierarchyLevel.Phase: + projects = await GetPhases(request.ParentId, cancellationToken); + break; + case ProjectHierarchyLevel.Task: + projects = await GetTasks(request.ParentId, cancellationToken); + break; + default: + return OperationResult.Failure("سطح سلسله مراتب نامعتبر است"); + } + await SetSkillFlags(projects, cancellationToken); + + var response = new GetProjectsListResponse(projects); + return OperationResult.Success(response); + } + + private async Task> GetProjects(Guid? parentId, CancellationToken cancellationToken) + { + var query = _context.Projects.AsQueryable(); + + // پروژه‌ها سطح بالا هستند و parentId ندارند، فقط در صورت null بودن parentId نمایش داده می‌شوند + if (parentId.HasValue) + { + return new List(); // پروژه‌ها parent ندارند + } + + var projects = await query + .OrderByDescending(p => p.CreationDate) + .ToListAsync(cancellationToken); + var result = new List(); + + foreach (var project in projects) + { + var percentage = await CalculateProjectPercentage(project, cancellationToken); + result.Add(new GetProjectListDto + { + Id = project.Id, + Name = project.Name, + Level = ProjectHierarchyLevel.Project, + ParentId = null, + Percentage = percentage + }); + } + + return result; + } + + private async Task> GetPhases(Guid? parentId, CancellationToken cancellationToken) + { + var query = _context.ProjectPhases.AsQueryable(); + + if (parentId.HasValue) + { + query = query.Where(x => x.ProjectId == parentId); + } + + var phases = await query + .OrderByDescending(p => p.CreationDate) + .ToListAsync(cancellationToken); + var result = new List(); + + foreach (var phase in phases) + { + var percentage = await CalculatePhasePercentage(phase, cancellationToken); + result.Add(new GetProjectListDto + { + Id = phase.Id, + Name = phase.Name, + Level = ProjectHierarchyLevel.Phase, + ParentId = phase.ProjectId, + Percentage = percentage + }); + } + + return result; + } + + private async Task> GetTasks(Guid? parentId, CancellationToken cancellationToken) + { + var query = _context.ProjectTasks.AsQueryable(); + + if (parentId.HasValue) + { + query = query.Where(x => x.PhaseId == parentId); + } + + var tasks = await query + .OrderByDescending(t => t.CreationDate) + .ToListAsync(cancellationToken); + var result = new List(); + + foreach (var task in tasks) + { + var percentage = await CalculateTaskPercentage(task, cancellationToken); + result.Add(new GetProjectListDto + { + Id = task.Id, + Name = task.Name, + Level = ProjectHierarchyLevel.Task, + ParentId = task.PhaseId, + Percentage = percentage + }); + } + + return result; + } + + private async Task SetSkillFlags(List projects, CancellationToken cancellationToken) + { + var projectIds = projects.Select(x => x.Id).ToList(); + + // تنها تسک‌ها sections دارند، بنابراین برای سطوح مختلف باید متفاوت عمل کنیم + List taskIds; + + switch (projects.FirstOrDefault()?.Level) + { + case ProjectHierarchyLevel.Project: + // برای پروژه‌ها، باید تمام تسک‌های زیرمجموعه را پیدا کنیم + var phaseIds = await _context.ProjectPhases + .Where(ph => projectIds.Contains(ph.ProjectId)) + .Select(ph => ph.Id) + .ToListAsync(cancellationToken); + + taskIds = await _context.ProjectTasks + .Where(t => phaseIds.Contains(t.PhaseId)) + .Select(t => t.Id) + .ToListAsync(cancellationToken); + break; + + case ProjectHierarchyLevel.Phase: + // برای فازها، تمام تسک‌های آن فازها را پیدا کنیم + taskIds = await _context.ProjectTasks + .Where(t => projectIds.Contains(t.PhaseId)) + .Select(t => t.Id) + .ToListAsync(cancellationToken); + break; + + case ProjectHierarchyLevel.Task: + // برای تسک‌ها، خود آنها taskIds هستند + taskIds = projectIds; + break; + + default: + return; + } + + if (!taskIds.Any()) + return; + + var sections = await _context.TaskSections + .Include(x => x.Skill) + .Where(x => taskIds.Contains(x.TaskId)) + .ToListAsync(cancellationToken); + + foreach (var project in projects) + { + List relevantTaskIds; + + switch (project.Level) + { + case ProjectHierarchyLevel.Project: + // برای پروژه، تمام تسک‌های زیرمجموعه + var projectPhaseIds = await _context.ProjectPhases + .Where(ph => ph.ProjectId == project.Id) + .Select(ph => ph.Id) + .ToListAsync(cancellationToken); + + relevantTaskIds = await _context.ProjectTasks + .Where(t => projectPhaseIds.Contains(t.PhaseId)) + .Select(t => t.Id) + .ToListAsync(cancellationToken); + break; + + case ProjectHierarchyLevel.Phase: + // برای فاز، تمام تسک‌های آن فاز + relevantTaskIds = await _context.ProjectTasks + .Where(t => t.PhaseId == project.Id) + .Select(t => t.Id) + .ToListAsync(cancellationToken); + break; + + case ProjectHierarchyLevel.Task: + // برای تسک، خود آن + relevantTaskIds = new List { project.Id }; + break; + + default: + continue; + } + + var projectSections = sections.Where(x => relevantTaskIds.Contains(x.TaskId)).ToList(); + project.HasBackend = projectSections.Any(x => x.Skill.Name == "Backend"); + project.HasFront = projectSections.Any(x => x.Skill.Name == "Frontend"); + project.HasDesign = projectSections.Any(x => x.Skill.Name == "UI/UX Design"); + } + } + + private async Task CalculateProjectPercentage(Project project, CancellationToken cancellationToken) + { + // گرفتن تمام فازهای پروژه + var phases = await _context.ProjectPhases + .Where(ph => ph.ProjectId == project.Id) + .ToListAsync(cancellationToken); + + if (!phases.Any()) + return 0; + + // محاسبه درصد هر فاز و میانگین‌گیری + var phasePercentages = new List(); + foreach (var phase in phases) + { + var phasePercentage = await CalculatePhasePercentage(phase, cancellationToken); + phasePercentages.Add(phasePercentage); + } + + return phasePercentages.Any() ? (int)phasePercentages.Average() : 0; + } + + private async Task CalculatePhasePercentage(ProjectPhase phase, CancellationToken cancellationToken) + { + // گرفتن تمام تسک‌های فاز + var tasks = await _context.ProjectTasks + .Where(t => t.PhaseId == phase.Id) + .ToListAsync(cancellationToken); + + if (!tasks.Any()) + return 0; + + // محاسبه درصد هر تسک و میانگین‌گیری + var taskPercentages = new List(); + foreach (var task in tasks) + { + var taskPercentage = await CalculateTaskPercentage(task, cancellationToken); + taskPercentages.Add(taskPercentage); + } + + return taskPercentages.Any() ? (int)taskPercentages.Average() : 0; + } + + private async Task CalculateTaskPercentage(ProjectTask task, CancellationToken cancellationToken) + { + // گرفتن تمام سکشن‌های تسک با activities + var sections = await _context.TaskSections + .Include(s => s.Activities) + .Where(s => s.TaskId == task.Id) + .ToListAsync(cancellationToken); + + if (!sections.Any()) + return 0; + + // محاسبه درصد هر سکشن و میانگین‌گیری + var sectionPercentages = new List(); + foreach (var section in sections) + { + var sectionPercentage = CalculateSectionPercentage(section); + sectionPercentages.Add(sectionPercentage); + } + + return sectionPercentages.Any() ? (int)sectionPercentages.Average() : 0; + } + + private static int CalculateSectionPercentage(TaskSection section) + { + // محاسبه کل زمان تخمین زده شده (اولیه + اضافی) + var totalEstimatedHours = section.FinalEstimatedHours.TotalHours; + + if (totalEstimatedHours <= 0) + return 0; + + // محاسبه کل زمان صرف شده از activities + var totalSpentHours = section.Activities.Sum(a => a.GetTimeSpent().TotalHours); + + // محاسبه درصد (حداکثر 100%) + var percentage = (totalSpentHours / totalEstimatedHours) * 100; + return Math.Min((int)Math.Round(percentage), 100); + } +} + diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/GetProjectsList/GetProjectsListQueryValidator.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/GetProjectsList/GetProjectsListQueryValidator.cs new file mode 100644 index 00000000..33141e46 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/GetProjectsList/GetProjectsListQueryValidator.cs @@ -0,0 +1,19 @@ +using FluentValidation; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Queries.GetProjectsList; + +public class GetProjectsListQueryValidator : AbstractValidator +{ + public GetProjectsListQueryValidator() + { + RuleFor(x => x.HierarchyLevel) + .IsInEnum().WithMessage("سطح ارسال شده معتبر نمی‌باشد."); + + When(x => x.HierarchyLevel != Domain.ProjectAgg.Enums.ProjectHierarchyLevel.Project, () => + { + RuleFor(x => x.ParentId) + .NotNull().WithMessage("شناسه والد باید برای سطوح غیر از پروژه ارسال شود."); + }); + } +} + diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/GetProjectsList/GetProjectsListResponse.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/GetProjectsList/GetProjectsListResponse.cs new file mode 100644 index 00000000..928501dd --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/GetProjectsList/GetProjectsListResponse.cs @@ -0,0 +1,5 @@ +namespace GozareshgirProgramManager.Application.Modules.Projects.Queries.GetProjectsList; + +public record GetProjectsListResponse( + List Projects); + diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectBoardList/ProjectBoardListQuery.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectBoardList/ProjectBoardListQuery.cs new file mode 100644 index 00000000..db180808 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectBoardList/ProjectBoardListQuery.cs @@ -0,0 +1,10 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application.Modules.Projects.Queries.GetProjectsList; +using GozareshgirProgramManager.Domain.ProjectAgg.Enums; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectBoardList; + +public record ProjectBoardListQuery: IBaseQuery> +{ +} + diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectBoardList/ProjectBoardListQueryHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectBoardList/ProjectBoardListQueryHandler.cs new file mode 100644 index 00000000..0edfdc0b --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectBoardList/ProjectBoardListQueryHandler.cs @@ -0,0 +1,98 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; +using Microsoft.EntityFrameworkCore; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectBoardList; + +public class ProjectBoardListQueryHandler : IBaseQueryHandler> +{ + private readonly IProgramManagerDbContext _programManagerDbContext; + private readonly IAuthHelper _authHelper; + + public ProjectBoardListQueryHandler(IProgramManagerDbContext programManagerDbContext, IAuthHelper authHelper) + { + _programManagerDbContext = programManagerDbContext; + _authHelper = authHelper; + } + + public async Task>> Handle(ProjectBoardListQuery request, + CancellationToken cancellationToken) + { + var currentUserId = _authHelper.GetCurrentUserId(); + var data = await _programManagerDbContext.TaskSections.AsNoTracking() + .Where(x => x.CurrentAssignedUserId == currentUserId) + .Where(x => x.InitialEstimatedHours > TimeSpan.Zero) + .Include(x => x.Task) + .ThenInclude(x => x.Phase) + .ThenInclude(x => x.Project) + .Include(x => x.Activities) + .Include(x => x.AdditionalTimes) + .ToListAsync(cancellationToken); + + var activityUserIds = data.SelectMany(x => x.Activities).Select(a => a.UserId).Distinct().ToList(); + var users = await _programManagerDbContext.Users.AsNoTracking() + .Where(x => activityUserIds.Contains(x.Id)) + .Select(x => new { x.Id, x.FullName }) + .ToDictionaryAsync(x => x.Id, x => x.FullName, cancellationToken); + + var result = data.Select(x => + { + // محاسبه یکبار برای هر Activity و Cache کردن نتیجه + var activityTimeData = x.Activities.Select(a => + { + var timeSpent = a.GetTimeSpent(); + return new + { + Activity = a, + TimeSpent = timeSpent, + TotalSeconds = timeSpent.TotalSeconds, + FormattedTime = timeSpent.ToString(@"hh\:mm") + }; + }).ToList(); + + // ادغام پشت سر هم فعالیت‌های یک کاربر + var mergedHistories = new List(); + foreach (var activityData in activityTimeData) + { + var lastHistory = mergedHistories.LastOrDefault(); + + // اگر آخرین history برای همین کاربر باشد، زمان‌ها را جمع می‌کنیم + if (lastHistory != null && lastHistory.UserId == activityData.Activity.UserId) + { + var totalTimeSpan = lastHistory.WorkedTimeSpan + activityData.TimeSpent; + lastHistory.WorkedTimeSpan = totalTimeSpan; + lastHistory.WorkedTime = totalTimeSpan.ToString(@"hh\:mm"); + } + else + { + // در غیر این صورت، یک history جدید اضافه می‌کنیم + mergedHistories.Add(new ProjectProgressHistoryDto() + { + UserId = activityData.Activity.UserId, + IsCurrentUser = activityData.Activity.UserId == currentUserId, + Name = users.GetValueOrDefault(activityData.Activity.UserId, "ناشناس"), + WorkedTime = activityData.FormattedTime, + WorkedTimeSpan = activityData.TimeSpent, + }); + } + } + + return new ProjectBoardListResponse() + { + Id = x.Id, + PhaseName = x.Task.Phase.Name, + ProjectName = x.Task.Phase.Project.Name, + TaskName = x.Task.Name, + SectionStatus = x.Status, + Progress = new ProjectProgressDto() + { + CompleteSecond = x.FinalEstimatedHours.TotalSeconds, + CurrentSecond = activityTimeData.Sum(a => a.TotalSeconds), + Histories = mergedHistories + } + }; + }).ToList(); + + return OperationResult>.Success(result); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectBoardList/ProjectBoardListResponse.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectBoardList/ProjectBoardListResponse.cs new file mode 100644 index 00000000..83421e89 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectBoardList/ProjectBoardListResponse.cs @@ -0,0 +1,28 @@ +using GozareshgirProgramManager.Domain.ProjectAgg.Enums; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectBoardList; + +public class ProjectBoardListResponse +{ + public Guid Id { get; set; } + public string ProjectName { get; set; } + public string PhaseName { get; set; } + public string TaskName { get; set; } + public ProjectProgressDto Progress { get; set; } + public TaskSectionStatus SectionStatus { get; set; } +} +public class ProjectProgressDto +{ + public double CurrentSecond { get; set; } + public double CompleteSecond { get; set; } + public List Histories { get; set; } +} + +public class ProjectProgressHistoryDto +{ + public string Name { get; set; } + public long UserId { get; set; } + public string WorkedTime { get; set; } + public TimeSpan WorkedTimeSpan { get; set; } + public bool IsCurrentUser { get; set; } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectSetTimeDetails/ProjectSetTimeDetailsQuery.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectSetTimeDetails/ProjectSetTimeDetailsQuery.cs new file mode 100644 index 00000000..4b2c08b9 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectSetTimeDetails/ProjectSetTimeDetailsQuery.cs @@ -0,0 +1,30 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Domain.ProjectAgg.Enums; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectSetTimeDetails; + +public record ProjectSetTimeDetailsQuery(Guid TaskId) + : IBaseQuery; +public record ProjectSetTimeResponse( + List SectionItems, + Guid Id, + ProjectHierarchyLevel Level); + +public record ProjectSetTimeResponseSections +{ + public string SkillName { get; init; } + public string UserName { get; init; } + public int InitialTime { get; set; } + public string InitialDescription { get; set; } + public int TotalEstimateTime { get; init; } + public int TotalAdditionalTime { get; init; } + public string InitCreationTime { get; init; } + public List AdditionalTimes { get; init; } + public Guid SectionId { get; set; } +} + +public class ProjectSetTimeResponseSectionAdditionalTime +{ + public int Time { get; init; } + public string Description { get; init; } +} diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectSetTimeDetails/ProjectSetTimeDetailsQueryHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectSetTimeDetails/ProjectSetTimeDetailsQueryHandler.cs new file mode 100644 index 00000000..f99f3370 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectSetTimeDetails/ProjectSetTimeDetailsQueryHandler.cs @@ -0,0 +1,80 @@ +using DNTPersianUtils.Core; +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Application.Modules.Projects.Commands.SetTimeProject; +using GozareshgirProgramManager.Application.Modules.Projects.DTOs; +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.ProjectAgg.Enums; +using Microsoft.EntityFrameworkCore; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectSetTimeDetails; + + +public class ProjectSetTimeDetailsQueryHandler + : IBaseQueryHandler +{ + private readonly IProgramManagerDbContext _context; + + public ProjectSetTimeDetailsQueryHandler(IProgramManagerDbContext context) + { + _context = context; + } + + public async Task> Handle(ProjectSetTimeDetailsQuery request, + CancellationToken cancellationToken) + { + var task = await _context.ProjectTasks + .Where(p => p.Id == request.TaskId) + .Include(x => x.Sections) + .ThenInclude(x => x.AdditionalTimes).AsNoTracking() + .FirstOrDefaultAsync(cancellationToken); + + if (task == null) + { + return OperationResult.NotFound("Project not found"); + } + var userIds = task.Sections.Select(x => x.OriginalAssignedUserId) + .Distinct().ToList(); + + var users = await _context.Users + .Where(x => userIds.Contains(x.Id)) + .AsNoTracking() + .ToListAsync(cancellationToken); + var skillIds = task.Sections.Select(x => x.SkillId) + .Distinct().ToList(); + + var skills = await _context.Skills + .Where(x => skillIds.Contains(x.Id)) + .AsNoTracking() + .ToListAsync(cancellationToken); + + var res = new ProjectSetTimeResponse( + task.Sections.Select(ts => + { + var user = users.FirstOrDefault(x => x.Id == ts.OriginalAssignedUserId); + var skill = skills.FirstOrDefault(x => x.Id == ts.SkillId); + return new ProjectSetTimeResponseSections + { + AdditionalTimes = ts.AdditionalTimes + .Select(x => new ProjectSetTimeResponseSectionAdditionalTime + { + Description = x.Reason ?? "", + Time = (int)x.Hours.TotalHours + }).ToList(), + InitCreationTime = ts.CreationDate.ToFarsi(), + SkillName = skill?.Name ?? "", + TotalAdditionalTime = (int)ts.GetTotalAdditionalTime().TotalHours, + TotalEstimateTime = (int)ts.FinalEstimatedHours.TotalHours, + UserName = user?.UserName ?? "", + SectionId = ts.Id, + InitialDescription = ts.InitialDescription ?? "", + InitialTime = (int)ts.InitialEstimatedHours.TotalHours + }; + }).ToList(), + task.Id, + ProjectHierarchyLevel.Task); + + + return OperationResult.Success(res); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectSetTimeDetails/ProjectSetTimeDetailsQueryValidator.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectSetTimeDetails/ProjectSetTimeDetailsQueryValidator.cs new file mode 100644 index 00000000..13952f46 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectSetTimeDetails/ProjectSetTimeDetailsQueryValidator.cs @@ -0,0 +1,13 @@ +using FluentValidation; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectSetTimeDetails; + +public class ProjectSetTimeDetailsQueryValidator:AbstractValidator +{ + public ProjectSetTimeDetailsQueryValidator() + { + RuleFor(x => x.TaskId) + .NotEmpty() + .WithMessage("شناسه پروژه نمی‌تواند خالی باشد."); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Roles/Commands/CreateRole/CreateRoleCommandHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Roles/Commands/CreateRole/CreateRoleCommandHandler.cs new file mode 100644 index 00000000..c5ef5b2c --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Roles/Commands/CreateRole/CreateRoleCommandHandler.cs @@ -0,0 +1,44 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.PermissionAgg.Entities; +using GozareshgirProgramManager.Domain.RoleAgg.Entities; +using GozareshgirProgramManager.Domain.RoleAgg.Repositories; + +namespace GozareshgirProgramManager.Application.Modules.Roles.Commands.CreateRole; + +public class CreateRoleCommandHandler : IBaseCommandHandler +{ + private readonly IRoleRepository _roleRepository; + private readonly IUnitOfWork _unitOfWork; + + public CreateRoleCommandHandler(IRoleRepository roleRepository, IUnitOfWork unitOfWork) + { + _roleRepository = roleRepository; + _unitOfWork = unitOfWork; + } + + public async Task Handle(CreateRoleCommand request, CancellationToken cancellationToken) + { + + if(string.IsNullOrWhiteSpace(request.RoleName)) + return OperationResult.Failure("نام نقش خالی است"); + if(!request.Permissions.Any()) + return OperationResult.Failure("هیچ دسترسی داده نشده است"); + var permissions = request.Permissions.Where(x => x > 0).Select(x => new Permission(x)).ToList(); + + var role = new Role(request.RoleName, request.GozareshgirRoleId, permissions); + await _roleRepository.CreateAsync(role); + await _unitOfWork.SaveChangesAsync(); + return OperationResult.Success(); + } +} + + +public record CreateRoleCommand : IBaseCommand +{ + public string RoleName { get; set; } + public List Permissions { get; set; } + + public long? GozareshgirRoleId { get; set; } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Roles/Commands/EditRole/EditRoleCommandHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Roles/Commands/EditRole/EditRoleCommandHandler.cs new file mode 100644 index 00000000..36e50fbb --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Roles/Commands/EditRole/EditRoleCommandHandler.cs @@ -0,0 +1,54 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.PermissionAgg.Entities; +using GozareshgirProgramManager.Domain.RoleAgg.Repositories; + +namespace GozareshgirProgramManager.Application.Modules.Roles.Commands.EditRole; + +public class EditRoleCommandHandler : IBaseCommandHandler +{ + private readonly IRoleRepository _roleRepository; + private readonly IUnitOfWork _unitOfWork; + + public EditRoleCommandHandler(IRoleRepository roleRepository, IUnitOfWork unitOfWork) + { + _roleRepository = roleRepository; + _unitOfWork = unitOfWork; + } + + public async Task Handle(EditRoleCommand request, CancellationToken cancellationToken) + { + if (_roleRepository.Exists(x => x.RoleName == request.RoleName && x.GozareshgirRoleId != request.GozareshgirRoleId)) + return OperationResult.Failure("نام نقش تکراری است"); + + if (string.IsNullOrWhiteSpace(request.RoleName)) + return OperationResult.Failure("نام نقش خالی است"); + + if(request.GozareshgirRoleId == null || request.GozareshgirRoleId == 0) + return OperationResult.Failure("آی دی نقش از سمت گزارشگیر خالی است"); + + var permissions = request.Permissions.Where(x => x > 0).Select(x => new Permission(x)).ToList(); + + + var role =await _roleRepository.GetByGozareshgirRoleIdAsync(request.GozareshgirRoleId); + + if (role != null) + { + role?.Edit(request.RoleName, permissions); + + await _unitOfWork.SaveChangesAsync(); + } + + return OperationResult.Success(); + + } +} + +public record EditRoleCommand : IBaseCommand +{ + public string RoleName { get; set; } + public List Permissions { get; set; } + + public long? GozareshgirRoleId { get; set; } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Roles/Queries/GetRoles/GetRolesQueryHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Roles/Queries/GetRoles/GetRolesQueryHandler.cs new file mode 100644 index 00000000..bcdb5fe1 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Roles/Queries/GetRoles/GetRolesQueryHandler.cs @@ -0,0 +1,76 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; +using Microsoft.EntityFrameworkCore; + +namespace GozareshgirProgramManager.Application.Modules.Roles.Queries.GetRoles; + +public class GetRolesQueryHandler : IBaseQueryHandler +{ + private readonly IProgramManagerDbContext _context; + + public GetRolesQueryHandler(IProgramManagerDbContext context) + { + _context = context; + } + + public async Task> Handle(GetRolesQuery request, CancellationToken cancellationToken) + { + var query = _context.Roles.AsQueryable(); + + if (!string.IsNullOrWhiteSpace(request.RoleName)) + query = query.Where(x => x.RoleName.Contains(request.RoleName)); + if (request.GozareshgirRoleId > 0) + query = query.Where(x => x.GozareshgirRoleId == request.GozareshgirRoleId); + + var roles = await query + .Select(p => new GetRolesDto() + { + Id = p.Id, + RoleName = p.RoleName, + GozareshgirRoleId = p.GozareshgirRoleId, + Permissions = p.Permissions.Select(x=>x.Code).ToList() + + }) + .ToListAsync(cancellationToken); + if(!roles.Any()) + return OperationResult.NotFound("یافت نشد"); + + var response = new GetRolesResponse( + roles + ); + + return OperationResult.Success(response); + + } +} + + +public record GetRolesQuery(string? RoleName, long? GozareshgirRoleId) : IBaseQuery; + +public record GetRolesResponse(List Role); + +public record GetRolesDto +{ + /// + /// آی دی نقش + /// + public long Id { get; set; } + + /// + /// نام نقش + /// + public string RoleName { get; set; } + + /// + /// آی دی نقش در گزارشگیر + /// + public long? GozareshgirRoleId { get; set; } + + /// + /// لیست کدهای دسترسی + /// + public List Permissions { get; set; } + + +} + diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/SalaryPaymentSettings/Commands/CreateSalarySettings/CreateSalarySettingsCommandHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/SalaryPaymentSettings/Commands/CreateSalarySettings/CreateSalarySettingsCommandHandler.cs new file mode 100644 index 00000000..95e57809 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/SalaryPaymentSettings/Commands/CreateSalarySettings/CreateSalarySettingsCommandHandler.cs @@ -0,0 +1,173 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities; +using GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Enums; +using GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Repositories; + +namespace GozareshgirProgramManager.Application.Modules.SalaryPaymentSettings.Commands.CreateSalarySettings; + +public class CreateSalarySettingsCommandHandler : IBaseCommandHandler +{ + readonly ISalaryPaymentSettingRepository _salaryPaymentSettingRepository; + readonly IUnitOfWork _unitOfWork; + + public CreateSalarySettingsCommandHandler(ISalaryPaymentSettingRepository salaryPaymentSettingRepository, IUnitOfWork unitOfWork) + { + _salaryPaymentSettingRepository = salaryPaymentSettingRepository; + _unitOfWork = unitOfWork; + } + + public async Task Handle(CreateSalarySettingsCommand request, CancellationToken cancellationToken) + { + + if(_salaryPaymentSettingRepository.Exists(x=>x.UserId == request.UserId)) + return OperationResult.Failure(" برای این پرسنل قبلا تنظیمات ایجاد شده است"); + + + if (string.IsNullOrWhiteSpace(request.MonthlySalary)) + return OperationResult.Failure("حقوق ماهانه وارد نشده اشت"); + double monthlySalary = 0; + try + { + monthlySalary = request.MonthlySalary.MoneyToDouble(); + } + catch (Exception e) + { + return OperationResult.Failure("مبلغ حقوق به درستی وارد نشده است"); + } + + + if (monthlySalary == 0) + return OperationResult.Failure("مبلغ حقوق به درستی وارد نشده است"); + + var workingHoursList = new List(); + foreach (var workingHours in request.WorkingHoursList) + { + var startShiftOne = new TimeSpan(); + var endShiftOne = new TimeSpan(); + var startShiftTwo = new TimeSpan(); + var endShiftTwo = new TimeSpan(); + var restTime = new TimeSpan(); + workingHours.HasShiftOne = false; + workingHours.HasRestTime = false; + workingHours.HasShiftTow = false; + try + { + if (!string.IsNullOrWhiteSpace(workingHours.StartShiftOne) && !string.IsNullOrWhiteSpace(workingHours.EndShiftOne)) + { + startShiftOne = TimeSpan.ParseExact(workingHours.StartShiftOne, @"hh\:mm", null); + endShiftOne = TimeSpan.ParseExact(workingHours.EndShiftOne, @"hh\:mm", null); + + workingHours.HasShiftOne = true; + + + if (!string.IsNullOrWhiteSpace(workingHours.RestTime)) + { + try + { + restTime = TimeSpan.ParseExact(workingHours.RestTime, @"hh\:mm", null); + workingHours.HasRestTime = true; + } + catch (Exception e) + { + return OperationResult.Failure("فرمت ساعت استراحت اشتباه وارد شده است"); + } + } + + } + + if (!string.IsNullOrWhiteSpace(workingHours.StartShiftTwo) && + !string.IsNullOrWhiteSpace(workingHours.EndShiftTwo)) + { + workingHours.HasRestTime = false; + workingHours.HasShiftTow = true; + + startShiftTwo = TimeSpan.ParseExact(workingHours.StartShiftTwo, @"hh\:mm", null); + endShiftTwo = TimeSpan.ParseExact(workingHours.EndShiftTwo, @"hh\:mm", null); + } + } + catch (Exception) + { + return OperationResult.Failure("فرمت ساعت اشتباه وارد شده است"); + } + + + + + workingHoursList.Add(new WorkingHours(startShiftOne,endShiftOne,startShiftTwo, endShiftTwo,restTime,workingHours.HasShiftOne,workingHours.HasShiftTow,workingHours.HasRestTime, workingHours.PersianDayOfWeek, workingHours.IsActiveDay)); + + } + + if(workingHoursList.Count < 7) + return OperationResult.Failure("خطا در تعداد روز های ارسال شده"); + var salarySetting = new SalaryPaymentSetting(request.HolidayWorking, request.UserId,monthlySalary, workingHoursList); + await _salaryPaymentSettingRepository.CreateAsync(salarySetting); + await _unitOfWork.SaveChangesAsync(); + return OperationResult.Success(); + + } +} + + +public record CreateSalarySettingsCommand(bool HolidayWorking, long UserId, string? MonthlySalary, List WorkingHoursList) : IBaseCommand; + + +public record WorkingHoursListDto +{ + /// + /// ساعت شروع شیفت کاری + /// + public string? StartShiftOne { get; set; } + + /// + /// ساعت پایان شیفت کاری + /// + public string? EndShiftOne { get; set; } + + + /// + /// ساعت شروع شیفت دوم کاری + /// + public string? StartShiftTwo { get; set; } + + /// + /// ساعت پایان شیفت دوم کاری + /// + public string? EndShiftTwo { get; set; } + + /// + /// مدت استراحت + /// + public string? RestTime { get; set; } + + + /// + /// آیا مقطع مار اول دارد + /// + public bool HasShiftOne { get; set; } + + /// + /// آیا مقطع کار دوم دارد + /// + public bool HasShiftTow { get; set; } + + /// + /// آیا ساعت استراحت دارد + /// + public bool HasRestTime { get; set; } + + + /// + /// عدد روز از ماه + /// + public PersianDayOfWeek PersianDayOfWeek { get; set; } + + + /// + /// آیا این روز هفته + /// فعال است + /// + public bool IsActiveDay { get; set; } +} + diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/SalaryPaymentSettings/Commands/EditSalarySettings/EditSalarySettingsCommandHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/SalaryPaymentSettings/Commands/EditSalarySettings/EditSalarySettingsCommandHandler.cs new file mode 100644 index 00000000..fe202a61 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/SalaryPaymentSettings/Commands/EditSalarySettings/EditSalarySettingsCommandHandler.cs @@ -0,0 +1,120 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Application.Modules.SalaryPaymentSettings.Commands.CreateSalarySettings; +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities; +using GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Repositories; + +namespace GozareshgirProgramManager.Application.Modules.SalaryPaymentSettings.Commands.EditSalarySettings; + +public class EditSalarySettingsCommandHandler : IBaseCommandHandler +{ + private readonly ISalaryPaymentSettingRepository _salaryPaymentSettingRepository; + private readonly IUnitOfWork _unitOfWork; + + public EditSalarySettingsCommandHandler(ISalaryPaymentSettingRepository salaryPaymentSettingRepository, IUnitOfWork unitOfWork) + { + _salaryPaymentSettingRepository = salaryPaymentSettingRepository; + _unitOfWork = unitOfWork; + } + + public async Task Handle(EditSalarySettingsCommand request, CancellationToken cancellationToken) + { + + var getSettings =await _salaryPaymentSettingRepository.GetSalarySettingByUserId(request.UserId); + if(getSettings == null) + return OperationResult.NotFound("یافت نشد"); + + if(string.IsNullOrWhiteSpace(request.MonthlySalary)) + return OperationResult.Failure("حقوق ماهانه وارد نشده اشت"); + double monthlySalary = 0; + try + { + monthlySalary = request.MonthlySalary.MoneyToDouble(); + } + catch (Exception e) + { + return OperationResult.Failure("مبلغ حقوق به درستی وارد نشده است"); + } + + if (monthlySalary == 0) + return OperationResult.Failure("مبلغ حقوق به درستی وارد نشده است"); + + + var workingHoursList = new List(); + foreach (var workingHours in request.WorkingHoursList) + { + var startShiftOne = new TimeSpan(); + var endShiftOne = new TimeSpan(); + var startShiftTwo = new TimeSpan(); + var endShiftTwo = new TimeSpan(); + var restTime = new TimeSpan(); + workingHours.HasShiftOne = false; + workingHours.HasRestTime = false; + workingHours.HasShiftTow = false; + try + { + if (!string.IsNullOrWhiteSpace(workingHours.StartShiftOne) && !string.IsNullOrWhiteSpace(workingHours.EndShiftOne)) + { + startShiftOne = TimeSpan.ParseExact(workingHours.StartShiftOne, @"hh\:mm", null); + endShiftOne = TimeSpan.ParseExact(workingHours.EndShiftOne, @"hh\:mm", null); + + workingHours.HasShiftOne = true; + + + if (!string.IsNullOrWhiteSpace(workingHours.RestTime)) + { + try + { + restTime = TimeSpan.ParseExact(workingHours.RestTime, @"hh\:mm", null); + workingHours.HasRestTime = true; + } + catch (Exception e) + { + return OperationResult.Failure("فرمت ساعت استراحت اشتباه وارد شده است"); + } + } + } + + if (!string.IsNullOrWhiteSpace(workingHours.StartShiftTwo) && + !string.IsNullOrWhiteSpace(workingHours.EndShiftTwo)) + { + workingHours.HasRestTime = false; + workingHours.HasShiftTow = true; + + startShiftTwo = TimeSpan.ParseExact(workingHours.StartShiftTwo, @"hh\:mm", null); + endShiftTwo = TimeSpan.ParseExact(workingHours.EndShiftTwo, @"hh\:mm", null); + } + } + catch (Exception) + { + return OperationResult.Failure("فرمت ساعت اشتباه وارد شده است"); + } + + + + + workingHoursList.Add(new WorkingHours(startShiftOne, endShiftOne, startShiftTwo, endShiftTwo, restTime, workingHours.HasShiftOne, workingHours.HasShiftTow, workingHours.HasRestTime, workingHours.PersianDayOfWeek, workingHours.IsActiveDay)); + + + + } + + + getSettings.Edit(request.HolidayWorking,monthlySalary, workingHoursList); + + + await _unitOfWork.SaveChangesAsync(); + return OperationResult.Success(); + } +} + + +public record EditSalarySettingsCommand(long UserId, bool HolidayWorking,string? MonthlySalary, List WorkingHoursList) : IBaseCommand; + + + + + + + diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/SalaryPaymentSettings/Queries/GetSalarySettingToEdit/GetSalarySettingToEditQueryHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/SalaryPaymentSettings/Queries/GetSalarySettingToEdit/GetSalarySettingToEditQueryHandler.cs new file mode 100644 index 00000000..c3bd3385 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/SalaryPaymentSettings/Queries/GetSalarySettingToEdit/GetSalarySettingToEditQueryHandler.cs @@ -0,0 +1,88 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Application.Modules.SalaryPaymentSettings.Commands.CreateSalarySettings; +using GozareshgirProgramManager.Domain._Common; +using Microsoft.EntityFrameworkCore; +using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database; + +namespace GozareshgirProgramManager.Application.Modules.SalaryPaymentSettings.Queries.GetSalarySettingToEdit; + +public class GetSalarySettingToEditQueryHandler : IBaseQueryHandler +{ + private readonly IProgramManagerDbContext _context; + + public GetSalarySettingToEditQueryHandler(IProgramManagerDbContext context) + { + _context = context; + } + + public async Task> Handle(GetSalarySettingToEditQuery request, CancellationToken cancellationToken) + { + var user =await _context.Users.FirstOrDefaultAsync(x => x.Id == request.UserId); + if(user == null) + return OperationResult.NotFound("کاربر یافت نشد"); + + var editSalarySettingsList = await _context.SalaryPaymentSettings + .Select(x => new GetSalarySettingToEdit() + { + Id = x.Id, + HolidayWorking = x.HolidayWorking, + UserId = x.UserId, + MonthlySalary = x.MonthlySalary.ToMoney(), + + WorkingHoursList = x.WorkingHoursList.Select(wh => new WorkingHoursListDto + { + StartShiftOne =wh.HasShiftOne ? wh.StartShiftOne.ToString(@"hh\:mm") : null, + EndShiftOne = wh.HasShiftOne ? wh.EndShiftOne.ToString(@"hh\:mm") : null, + StartShiftTwo = wh.HasShiftTow ? wh.StartShiftTwo.ToString(@"hh\:mm") : null, + EndShiftTwo = wh.HasShiftTow ? wh.EndShiftTwo.ToString(@"hh\:mm") :null, + RestTime = wh.HasRestTime ? wh.RestTime.ToString(@"hh\:mm") : null, + HasRestTime = wh.HasRestTime, + HasShiftOne = wh.HasShiftOne, + HasShiftTow = wh.HasShiftTow, + PersianDayOfWeek = wh.PersianDayOfWeek, + IsActiveDay = wh.IsActiveDay + }).OrderBy(wh=>wh.PersianDayOfWeek).ToList(), + + }).FirstOrDefaultAsync(x => x.UserId == request.UserId); + + var response = new GetSalarySettingToEditResponse(request.UserId,user.FullName,editSalarySettingsList); + + return OperationResult.Success(response); + + } +} + +public record GetSalarySettingToEditResponse(long UserId, string FullName, GetSalarySettingToEdit EditSalarySettingsList); + +public record GetSalarySettingToEditQuery(long UserId) :IBaseQuery; + + +public record GetSalarySettingToEdit +{ + /// + /// ای دی کاربر + /// + public long Id { get; set; } + /// + /// آی دی کاربر + /// + public long UserId { get; set; } + + /// + /// کار در تعطیلات رسمی + /// + public bool HolidayWorking { get; set; } + + /// + /// حقوق ماهانه + /// + public string MonthlySalary { get; set; } + + /// + /// لیست روزهای هفته و ساعات کاری + /// + public List WorkingHoursList { get; set; } +} + + diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/SalaryPaymentSettings/Queries/GetUserListWhoHaveSettings/GetUserListWhoHaveSettingsQueryHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/SalaryPaymentSettings/Queries/GetUserListWhoHaveSettings/GetUserListWhoHaveSettingsQueryHandler.cs new file mode 100644 index 00000000..2e9361e6 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/SalaryPaymentSettings/Queries/GetUserListWhoHaveSettings/GetUserListWhoHaveSettingsQueryHandler.cs @@ -0,0 +1,111 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; + +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Enums; +using Microsoft.EntityFrameworkCore; + +namespace GozareshgirProgramManager.Application.Modules.SalaryPaymentSettings.Queries.GetUserListWhoHaveSettings; + +public class GetUserListWhoHaveSettingsQueryHandler : IBaseQueryHandler +{ + private readonly IProgramManagerDbContext _context; + + public GetUserListWhoHaveSettingsQueryHandler(IProgramManagerDbContext context) + { + _context = context; + } + + public async Task> Handle(GetUserListWhoHaveSettingsQuery request, CancellationToken cancellationToken) + { + var query = await ( + from u in _context.Users + join s in _context.SalaryPaymentSettings + on u.Id equals s.UserId into settingsGroup + select new GetUserWhoHaveSettingsDto + { + UserId = u.Id, + FullName = u.FullName, + HasSalarySettings = settingsGroup.Any(), + MontlySalary = settingsGroup.Any() ? settingsGroup.FirstOrDefault().MonthlySalary.ToMoney() : "", + WeeklyWorkingTimeAvrageInt = settingsGroup + .SelectMany(x => x.WorkingHoursList) + .Sum(w => (int?)w.ShiftDurationInMinutes) ?? 0 + } + ).ToListAsync(cancellationToken); + + + + if (!string.IsNullOrWhiteSpace(request.FullName)) + query = query.Where(x => x.FullName.Contains(request.FullName)).ToList(); + + if (request.HasSalarySettings != HasSalarySettings.Default) + { + bool hasSettings = request.HasSalarySettings == HasSalarySettings.HasSettings; + + query = query.Where(x => x.HasSalarySettings == hasSettings).ToList(); + } + + var operationQuery = query.Select(user => + { + var weeklyWorkingTimeAvrage = user.WeeklyWorkingTimeAvrageInt.ConvertIntDurationToHoursAndMinutes(); + + return new GetUserWhoHaveSettingsDto + { + UserId = user.UserId, + FullName = user.FullName, + HasSalarySettings = user.HasSalarySettings, + MontlySalary = user.MontlySalary, + WeeklyWorkingTimeAvrageInt = user.WeeklyWorkingTimeAvrageInt, + WeeklyWorkingTimeAvrage = weeklyWorkingTimeAvrage + }; + }).ToList(); + var response = new GetUserListWhoHaveSettingsResponse(operationQuery); + + return OperationResult.Success(response); + + + } +} + + +public record GetUserListWhoHaveSettingsQuery(string? FullName, HasSalarySettings HasSalarySettings) : IBaseQuery; + +public record GetUserListWhoHaveSettingsResponse(List UserList); + +public record GetUserWhoHaveSettingsDto +{ + /// + /// نام و نام خانوادگی + /// + public string FullName { get; set; } + + /// + /// آی دی کاربر + /// + public long UserId { get; set; } + + /// + /// آیا کاربر دارای تنظیمات حقوق است؟ + /// + public bool HasSalarySettings { get; set; } + + /// + /// میانگین ساعت کار + /// عددی مجموع دقایق + /// + public int WeeklyWorkingTimeAvrageInt { get; set; } + + /// + /// میانگین ساعت کار در هفته + /// رشته ساعت و دقیقه + /// + public string WeeklyWorkingTimeAvrage { get; set; } + + + /// + /// حقوق ماهانه + /// + public string MontlySalary { get; set; } + +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Skills/DTOs/SkillDto.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Skills/DTOs/SkillDto.cs new file mode 100644 index 00000000..75d052ce --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Skills/DTOs/SkillDto.cs @@ -0,0 +1,7 @@ +namespace GozareshgirProgramManager.Application.Modules.Skills.DTOs; + +public class SkillDto +{ + public Guid Id { get; set; } + public string Name { get; set; } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Skills/Queries/GetSkillList/GetSkillListCommandHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Skills/Queries/GetSkillList/GetSkillListCommandHandler.cs new file mode 100644 index 00000000..061597c9 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Skills/Queries/GetSkillList/GetSkillListCommandHandler.cs @@ -0,0 +1,33 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Application.Modules.Skills.DTOs; +using Microsoft.EntityFrameworkCore; + +namespace GozareshgirProgramManager.Application.Modules.Skills.Queries.GetSkillList; + +public record GetSkillListQuery() : IBaseQuery; +public record GetSkillListResponse(List Skills); + +public class GetSkillListCommandHandler:IBaseQueryHandler +{ + private readonly IProgramManagerDbContext _dbContext; + + public GetSkillListCommandHandler(IProgramManagerDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task> Handle(GetSkillListQuery request, CancellationToken cancellationToken) + { + var skills =await _dbContext.Skills + .Select(s => new SkillDto + { + Id = s.Id, + Name = s.Name + }) + .ToListAsync(cancellationToken: cancellationToken); + + var response = new GetSkillListResponse(skills); + return OperationResult.Success(response); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/CreateUser/CreateUserCommand.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/CreateUser/CreateUserCommand.cs new file mode 100644 index 00000000..4eba06a0 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/CreateUser/CreateUserCommand.cs @@ -0,0 +1,5 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; + +namespace GozareshgirProgramManager.Application.Modules.Users.Commands.CreateUser; + +public record CreateUserCommand(string FullName, string UserName, string Password, string Mobile, string? Email, long? AccountId, List Roles) : IBaseCommand; \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/CreateUser/CreateUserCommandHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/CreateUser/CreateUserCommandHandler.cs new file mode 100644 index 00000000..535697b3 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/CreateUser/CreateUserCommandHandler.cs @@ -0,0 +1,43 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.RoleUserAgg; +using GozareshgirProgramManager.Domain.UserAgg.Entities; +using GozareshgirProgramManager.Domain.UserAgg.Repositories; + +namespace GozareshgirProgramManager.Application.Modules.Users.Commands.CreateUser; + +public class CreateUserCommandHandler : IBaseCommandHandler +{ + private readonly IUserRepository _userRepository; + private readonly IUnitOfWork _unitOfWork; + + public CreateUserCommandHandler(IUnitOfWork unitOfWork, IUserRepository userRepository) + { + _unitOfWork = unitOfWork; + _userRepository = userRepository; + } + + public async Task Handle(CreateUserCommand request, CancellationToken cancellationToken) + { + + #region CustomValidation + if (_userRepository.Exists(x => x.FullName == request.FullName)) + return OperationResult.Failure("نام و خانوادگی تکراری است"); + if (_userRepository.Exists(x => x.UserName == request.UserName)) + return OperationResult.Failure("نام کاربری تکراری است"); + if (_userRepository.Exists(x=> !string.IsNullOrWhiteSpace(x.Mobile) && x.Mobile == request.Mobile)) + return OperationResult.ValidationError("این شماره همراه قبلا به فرد دیگری اختصاص داده شده است"); + if(request.AccountId == 0) + return OperationResult.Failure("آی دی اکانت، از سمت گزارشگیر صفر است"); + #endregion + + var userRoles = request.Roles.Where(x => x > 0).Select(x => new RoleUser(x)).ToList() ; + var create = new User(request.FullName, request.UserName, request.Password, request.Mobile, + request.Email, request?.AccountId, userRoles); + + await _userRepository.CreateAsync(create); + await _unitOfWork.SaveChangesAsync(cancellationToken); + return OperationResult.Success(); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/CreateUser/CreateUserCommandValidators.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/CreateUser/CreateUserCommandValidators.cs new file mode 100644 index 00000000..68f9f1a7 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/CreateUser/CreateUserCommandValidators.cs @@ -0,0 +1,24 @@ +using FluentValidation; + +namespace GozareshgirProgramManager.Application.Modules.Users.Commands.CreateUser; + +public class CreateUserCommandValidators : AbstractValidator +{ + public CreateUserCommandValidators() + { + RuleFor(x => x.FullName) + .NotEmpty() + .NotNull() + .WithMessage("نام و نام خانوادگی نمی تواند خالی باشد"); + + RuleFor(x => x.Mobile) + .NotNull().NotEmpty().WithMessage("شماره همراه نمی تواند خالی باشد"); + RuleFor(x=>x.Mobile) + .Length(11).WithMessage("طول شماره همراه می بایست 11 رقم باشد"); + RuleFor(x => x.UserName) + .NotEmpty().NotNull().WithMessage("نام کاربری نمیتوان خالی باشد"); + + + + } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/EditUser/EditUserCommandHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/EditUser/EditUserCommandHandler.cs new file mode 100644 index 00000000..1920f1fb --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Commands/EditUser/EditUserCommandHandler.cs @@ -0,0 +1,34 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.RoleUserAgg; +using GozareshgirProgramManager.Domain.UserAgg.Repositories; + +namespace GozareshgirProgramManager.Application.Modules.Users.Commands.EditUser; + +public class EditUserCommandHandler :IBaseCommandHandler +{ + private readonly IUserRepository _userRepository; + private readonly IUnitOfWork _unitOfWork; + + public EditUserCommandHandler(IUserRepository userRepository, IUnitOfWork unitOfWork) + { + _userRepository = userRepository; + _unitOfWork = unitOfWork; + } + + public async Task Handle(EditUserCommand request, CancellationToken cancellationToken) + { + var user = await _userRepository.GetByGozareshgirAccountId(request.AccountId); + if (user != null) + { + var userRoles = request.Roles.Where(x => x > 0).Select(x => new RoleUser(x)).ToList(); + user.Edit(request.FullName, request.UserName, request.Mobile, userRoles, request.IsActive); + await _unitOfWork.SaveChangesAsync(); + } + + return OperationResult.Success(); + } +} + +public record EditUserCommand(string FullName, string UserName, string Mobile,long AccountId, List Roles, bool IsActive) : IBaseCommand; \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Queries/GetSingleUser/GetSingleUserQueryHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Queries/GetSingleUser/GetSingleUserQueryHandler.cs new file mode 100644 index 00000000..41b7d4e8 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Queries/GetSingleUser/GetSingleUserQueryHandler.cs @@ -0,0 +1,126 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; +using Microsoft.EntityFrameworkCore; + +namespace GozareshgirProgramManager.Application.Modules.Users.Queries.GetSingleUser; + +public class GetSingleUserQueryHandler : IBaseQueryHandler +{ + private readonly IProgramManagerDbContext _context; + + public GetSingleUserQueryHandler(IProgramManagerDbContext context) + { + _context = context; + } + + public async Task> Handle(GetSingleUserQuery request, CancellationToken cancellationToken) + { + + if (!string.IsNullOrWhiteSpace(request.accountId)) + { + long accountId = 0; + try + { + accountId = Convert.ToInt64(request.accountId); + } + catch (Exception e) + { + return (OperationResult)OperationResult.Failure("فقط عدد وارد کنید"); + } + + + if (accountId > 0) + { + var user = await _context.Users + .FirstOrDefaultAsync(x => x.AccountId == accountId); + + + if(user != null) + { + List roles = user.RoleUser.Select(x => x.RoleId).ToList(); + var response = new GetSingleUserResponse + { + Id = user.Id, + FullName = user.FullName, + UserName = user.UserName, + ProfilePhotoPath = user.ProfilePhotoPath, + Mobile = user.Mobile, + IsActive = user.IsActive, + AccountId = user.AccountId, + Roles = roles, + RoleListDto = await _context.Roles.Where(x => roles.Contains(x.Id)).Select(x=> new RoleListDto() + { + RoleName = x.RoleName, + RoleId = x.Id, + Permissions = x.Permissions.Select(x=>x.Code).ToList() + }).ToListAsync(), + }; + + return OperationResult.Success(response); + } + else + { + return OperationResult.NotFound("کاربر یافت نشد"); + } + } + } + + return OperationResult.Failure("آی دی اکانت گزارشگیر پر نشده است"); + } +} + + +public record GetSingleUserResponse +{ + public long Id { get; set; } + /// + /// نام و نام خانوادگی + /// + public string FullName { get; set; } + + /// + /// نام کاربری + /// + public string UserName { get; set; } + + + + /// + /// مسیر عکس پروفایل + /// + public string ProfilePhotoPath { get; set; } + + /// + /// شماره موبایل + /// + public string Mobile { get; set; } + + + /// + /// فعال/غیر فعال بودن یوزر + /// + public bool IsActive { get; set; } + + /// + /// آی دی کاربر در گزارشگیر + /// + public long? AccountId { get; set; } + + /// + /// نقش ها + /// + public List Roles { get; set; } + + public List RoleListDto { get; set; } +}; + + +public record RoleListDto +{ + public string RoleName { get; set; } + public long RoleId { get; set; } + public List Permissions { get; set; } + +} + +public record GetSingleUserQuery(string? accountId) : IBaseQuery; \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Queries/GetUserSelectList/GetUserSelectListQueryHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Queries/GetUserSelectList/GetUserSelectListQueryHandler.cs new file mode 100644 index 00000000..7b45273a --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Queries/GetUserSelectList/GetUserSelectListQueryHandler.cs @@ -0,0 +1,48 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Application.Modules.Users.Queries.GetSingleUser; +using Microsoft.EntityFrameworkCore; + +namespace GozareshgirProgramManager.Application.Modules.Users.Queries.GetUserSelectList; + +public class GetUserSelectListQueryHandler : IBaseQueryHandler +{ + private readonly IProgramManagerDbContext _context; + + public GetUserSelectListQueryHandler(IProgramManagerDbContext context) + { + _context = context; + } + + public async Task> Handle(GetUserSelectListQuery request, CancellationToken cancellationToken) + { + + var query = await _context.Users.Select(x => new GetUserSelectListDto() + { + FullName = x.FullName, + Id = x.Id + }).ToListAsync(); + + var response = new GetUserSelectListResponse(query); + + + return OperationResult.Success(response); + } +} + + +public record GetUserSelectListResponse(List? GetUserSelectListDto); + +public record GetUserSelectListDto +{ + /// + /// نام و نام خانوادگی + /// + public string FullName { get; set; } + + /// + /// آی دی کاربر + /// + public long Id { get; set; } +} +public record GetUserSelectListQuery() : IBaseQuery; \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Queries/GetUsers/GetUsersQuery.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Queries/GetUsers/GetUsersQuery.cs new file mode 100644 index 00000000..9a3e15e8 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Queries/GetUsers/GetUsersQuery.cs @@ -0,0 +1,5 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; + +namespace GozareshgirProgramManager.Application.Modules.Users.Queries.GetUsers; + +public record GetUsersQuery(string? FullName, string? UserName, string? Mobile) : IBaseQuery; \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Queries/GetUsers/GetUsersQueryHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Queries/GetUsers/GetUsersQueryHandler.cs new file mode 100644 index 00000000..cb6467f4 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Queries/GetUsers/GetUsersQueryHandler.cs @@ -0,0 +1,49 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; +using Microsoft.EntityFrameworkCore; + +namespace GozareshgirProgramManager.Application.Modules.Users.Queries.GetUsers; + +public class GetUsersQueryHandler :IBaseQueryHandler +{ + private readonly IProgramManagerDbContext _context; + + public GetUsersQueryHandler(IProgramManagerDbContext context) + { + _context = context; + } + + public async Task> Handle(GetUsersQuery request, CancellationToken cancellationToken) + { + var query = _context.Users.AsQueryable(); + + //if (request.ParentId != null) + //{ + // query = query.Where(x => x.ParentId == request.ParentId); + //} + + var users = await query + .Select(p => new GetUserDto() + { + + FullName = p.FullName, + Mobile = p.Mobile, + UserName = p.UserName, + AccountId = p.AccountId, + IsActive = p.IsActive, + ProfilePhotoPath = p.ProfilePhotoPath, + + + }) + .ToListAsync(cancellationToken); + + var response = new GetUsersResponse( + users + ); + + return OperationResult.Success(response); + } + + + +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Queries/GetUsers/GetUsersResponse.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Queries/GetUsers/GetUsersResponse.cs new file mode 100644 index 00000000..e1cd043c --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Users/Queries/GetUsers/GetUsersResponse.cs @@ -0,0 +1,46 @@ +namespace GozareshgirProgramManager.Application.Modules.Users.Queries.GetUsers; + +public record GetUsersResponse(List User); + +public record GetUserDto +{ + /// + /// نام و نام خانوادگی + /// + public string FullName { get; set; } + + /// + /// نام کاربری + /// + public string UserName { get; set; } + + + + /// + /// مسیر عکس پروفایل + /// + public string ProfilePhotoPath { get; set; } + + /// + /// شماره موبایل + /// + public string Mobile { get; set; } + + + /// + /// فعال/غیر فعال بودن یوزر + /// + public bool IsActive { get; set; } + + /// + /// آی دی کاربر در گزارشگیر + /// + public long? AccountId { get; set; } + + /// + /// نقش ها + /// + public List Roles { get; set; } + +} + diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Bootstrapper/DependencyInjection.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Bootstrapper/DependencyInjection.cs new file mode 100644 index 00000000..07aaa222 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Bootstrapper/DependencyInjection.cs @@ -0,0 +1,22 @@ +using System.Reflection; +using GozareshgirProgramManager.Application.Interfaces; +using Microsoft.Extensions.DependencyInjection; + +namespace GozareshgirProgramManager.Application._Bootstrapper; + +public static class DependencyInjection +{ + public static IServiceCollection AddProgramManagerApplication(this IServiceCollection services) + { + services.AddMediatR(cfg => + { + cfg.RegisterServicesFromAssembly(Assembly.GetExecutingAssembly()); + cfg.LicenseKey = + "eyJhbGciOiJSUzI1NiIsImtpZCI6Ikx1Y2t5UGVubnlTb2Z0d2FyZUxpY2Vuc2VLZXkvYmJiMTNhY2I1OTkwNGQ4OWI0Y2IxYzg1ZjA4OGNjZjkiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2x1Y2t5cGVubnlzb2Z0d2FyZS5jb20iLCJhdWQiOiJMdWNreVBlbm55U29mdHdhcmUiLCJleHAiOiIxNzk2MDgzMjAwIiwiaWF0IjoiMTc2NDU5NTE2OSIsImFjY291bnRfaWQiOiIwMTlhZGExMDA0MzA3M2Y5ODhhNWY0MmJmZDdlYTE3OCIsImN1c3RvbWVyX2lkIjoiY3RtXzAxa2JkMTJ4eXNnMHB6MjR0YnhqeXA0a2p3Iiwic3ViX2lkIjoiLSIsImVkaXRpb24iOiIwIiwidHlwZSI6IjIifQ.Gl0FB9XoQMJQgzdCh9gplRirYvmkDJYXD8tfLiWkRAeQJ2zlFdoHw7btxGrUVisI_ZfSxK2kkUB_LLty2eArbeZb5Ja1_xexgzTv3CJ4TnacT0FoVOc8eLeGCbJmmXtSt6CW89XwzvV_taiSSkcdsnATNTH0MEBLqCkKw4FMpSXqrPxCgakXB-pcyeqeTO9a0DD5XjBVITGaslUUFgnBGirsLdHRgL9AYVty3EzWTBH9WBcc4dHyZ5YUDMzsIab5elc-pmOLCXAJviamG9Afsaq4N88IMjsYvq6ihw_EAsmQH1K8WNunFMN8VjwO5csHmgKJ6wajONH7kUaMWNxRrQ"; + }); + + + return services; + } +} + diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Behaviors/CachingBehavior.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Behaviors/CachingBehavior.cs new file mode 100644 index 00000000..e69de29b diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Behaviors/LoggingBehavior.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Behaviors/LoggingBehavior.cs new file mode 100644 index 00000000..e69de29b diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Behaviors/PerformanceBehavior.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Behaviors/PerformanceBehavior.cs new file mode 100644 index 00000000..e69de29b diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Behaviors/TransactionBehavior.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Behaviors/TransactionBehavior.cs new file mode 100644 index 00000000..c6cd15d5 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Behaviors/TransactionBehavior.cs @@ -0,0 +1,42 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace GozareshgirProgramManager.Application._Common.Behaviors; + +public class TransactionBehavior : IPipelineBehavior + where TRequest : IBaseCommand +{ + private readonly IProgramManagerDbContext _dbContext; + + public TransactionBehavior(IProgramManagerDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task Handle( + TRequest request, + RequestHandlerDelegate next, + CancellationToken cancellationToken) + { + // اگر تراکنش فعال است، ادامه بده + if (_dbContext is not DbContext efContext) + return await next(); + if (efContext.Database.CurrentTransaction != null) + return await next(); + + await using var transaction = await efContext.Database.BeginTransactionAsync(cancellationToken); + try + { + var response = await next(); + await _dbContext.SaveChangesAsync(cancellationToken); + await transaction.CommitAsync(cancellationToken); + return response; + } + catch + { + await transaction.RollbackAsync(cancellationToken); + throw; + } + } +} diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Behaviors/ValidationBehavior.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Behaviors/ValidationBehavior.cs new file mode 100644 index 00000000..a1473666 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Behaviors/ValidationBehavior.cs @@ -0,0 +1,40 @@ +using FluentValidation; +using GozareshgirProgramManager.Application._Common.Interfaces; +using MediatR; + +namespace GozareshgirProgramManager.Application._Common.Behaviors; + +public class ValidationBehavior : IPipelineBehavior + where TRequest : IBaseCommand +{ + private readonly IEnumerable> _validators; + + public ValidationBehavior(IEnumerable> validators) + { + _validators = validators; + } + + public async Task Handle( + TRequest request, + RequestHandlerDelegate next, + CancellationToken cancellationToken) + { + if (!_validators.Any()) + return await next(); + + var context = new ValidationContext(request); + + var validationResults = await Task.WhenAll( + _validators.Select(v => v.ValidateAsync(context, cancellationToken))); + + var failures = validationResults + .SelectMany(r => r.Errors) + .Where(f => f != null) + .ToList(); + + if (failures.Count != 0) + throw new ValidationException(failures); + + return await next(); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Extensions/EnumExtensions.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Extensions/EnumExtensions.cs new file mode 100644 index 00000000..e69de29b diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Extensions/QueryableExtensions.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Extensions/QueryableExtensions.cs new file mode 100644 index 00000000..979befac --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Extensions/QueryableExtensions.cs @@ -0,0 +1,19 @@ +namespace GozareshgirProgramManager.Application._Common.Extensions; + +public static class QueryableExtensions +{ + public static IQueryable ApplyPagination(this IQueryable query, int page, int pageSize = 30) + { + if (page <= 0) page = 1; + if (pageSize <= 0) pageSize = 10; + + return query.Skip((page - 1) * pageSize).Take(pageSize); + } + public static IEnumerable ApplyPagination(this IEnumerable source, int page, int pageSize = 30) + { + if (page <= 0) page = 1; + if (pageSize <= 0) pageSize = 10; + + return source.Skip((page - 1) * pageSize).Take(pageSize); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Extensions/StringExtensions.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Extensions/StringExtensions.cs new file mode 100644 index 00000000..e69de29b diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Interfaces/IAuthHelper.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Interfaces/IAuthHelper.cs new file mode 100644 index 00000000..a41dad2b --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Interfaces/IAuthHelper.cs @@ -0,0 +1,83 @@ +using System.Security.Claims; + +namespace GozareshgirProgramManager.Application._Common.Interfaces; + +/// +/// رابط کمکی برای کار با JWT و HttpContext +/// این interface فقط متدهای helper دارد و هیچ عملیات دیتابیسی ندارد +/// +public interface IAuthHelper +{ + // ==================== Token Generation ==================== + // LoginSession SignIn(long userId, string userName, string fullName, long accountId, List roles); + // /// + // /// تولید Access Token + // /// + // string GenerateAccessToken(long userId, string userName, string fullName, long? accountId, List roles); + + // /// + // /// تولید Refresh Token + // /// + // string GenerateRefreshToken(); + + // /// + // /// دریافت تاریخ انقضای Refresh Token + // /// + // DateTime GetRefreshTokenExpiration(); + + // ==================== Token Validation ==================== + // + // /// + // /// اعتبارسنجی توکن و استخراج Claims + // /// + // ClaimsPrincipal? ValidateToken(string token); + + // /// + // /// اعتبارسنجی توکن منقضی شده (بدون چک زمان انقضا) + // /// + // ClaimsPrincipal? ValidateExpiredToken(string token); + + // /// + // /// استخراج UserId از توکن (حتی اگر منقضی شده باشد) + // /// + // long? GetUserIdFromToken(string token); + + // ==================== HttpContext Helpers ==================== + + /// + /// دریافت IP Address کاربر جاری + /// + string? GetClientIpAddress(); + + + // /// + // /// دریافت Refresh Token از Cookie + // /// + // string? GetRefreshTokenFromCookie(); + + // ==================== Current User Claims ==================== + + /// + /// بررسی احراز هویت کاربر جاری + /// + bool IsAuthenticated(); + + /// + /// دریافت شناسه کاربر جاری از Claims + /// + long? GetCurrentUserId(); + + /// + /// دریافت نام کامل کاربر جاری از Claims + /// + string? GetCurrentFullName(); + + +} +public class LoginSession +{ + public string AccessToken { get; set; } + public string RefreshToken { get; set; } + public DateTime RefreshTokenExpiration { get; set; } + public DateTime AccessTokenExpiration { get; set; } +} diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Interfaces/IBaseCommand.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Interfaces/IBaseCommand.cs new file mode 100644 index 00000000..1b469f03 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Interfaces/IBaseCommand.cs @@ -0,0 +1,14 @@ +using GozareshgirProgramManager.Application._Common.Models; +using MediatR; + +namespace GozareshgirProgramManager.Application._Common.Interfaces; + +public interface IBaseCommand : IRequest +{ +} + +public interface IBaseCommand : IRequest> +{ +} + + diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Interfaces/IBaseCommandHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Interfaces/IBaseCommandHandler.cs new file mode 100644 index 00000000..3b699cb3 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Interfaces/IBaseCommandHandler.cs @@ -0,0 +1,13 @@ +using GozareshgirProgramManager.Application._Common.Models; +using MediatR; + +namespace GozareshgirProgramManager.Application._Common.Interfaces; + +public interface IBaseCommandHandler : IRequestHandler + where TCommand : IBaseCommand +{ +} +public interface IBaseCommandHandler : IRequestHandler> + where TCommand : IBaseCommand +{ +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Interfaces/IBasePaginationQuery.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Interfaces/IBasePaginationQuery.cs new file mode 100644 index 00000000..979a93f3 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Interfaces/IBasePaginationQuery.cs @@ -0,0 +1,10 @@ +using MediatR; +using GozareshgirProgramManager.Application._Common.Models; + +namespace GozareshgirProgramManager.Application._Common.Interfaces; + +public interface IBasePaginationQuery : IRequest>> +{ + int PageIndex { get; set; } + int PageSize { get; set; } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Interfaces/IBasePaginationQueryHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Interfaces/IBasePaginationQueryHandler.cs new file mode 100644 index 00000000..5d9c4bbf --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Interfaces/IBasePaginationQueryHandler.cs @@ -0,0 +1,12 @@ +using GozareshgirProgramManager.Application._Common.Models; +using MediatR; + +namespace GozareshgirProgramManager.Application._Common.Interfaces; + +public interface IBasePaginationQueryHandler + : IRequestHandler>> + where TQuery : PaginationRequest, IBasePaginationQuery + where TResponse : class +{ + +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Interfaces/IBaseQuery.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Interfaces/IBaseQuery.cs new file mode 100644 index 00000000..146e2c33 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Interfaces/IBaseQuery.cs @@ -0,0 +1,9 @@ +using MediatR; +using GozareshgirProgramManager.Application._Common.Models; + +namespace GozareshgirProgramManager.Application._Common.Interfaces; + +public interface IBaseQuery : IRequest> +{ +} + diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Interfaces/IBaseQueryHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Interfaces/IBaseQueryHandler.cs new file mode 100644 index 00000000..bd8650ba --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Interfaces/IBaseQueryHandler.cs @@ -0,0 +1,10 @@ +using MediatR; +using GozareshgirProgramManager.Application._Common.Models; + +namespace GozareshgirProgramManager.Application._Common.Interfaces; + +public interface IBaseQueryHandler : IRequestHandler> + where TQuery : IBaseQuery +{ +} + diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Interfaces/IProgramManagerDbContext.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Interfaces/IProgramManagerDbContext.cs new file mode 100644 index 00000000..1a477bec --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Interfaces/IProgramManagerDbContext.cs @@ -0,0 +1,32 @@ +using GozareshgirProgramManager.Domain.CheckoutAgg.Entities; +using GozareshgirProgramManager.Domain.CustomerAgg; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.RoleAgg.Entities; +using GozareshgirProgramManager.Domain.RoleUserAgg; +using GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities; +using GozareshgirProgramManager.Domain.SkillAgg.Entities; +using GozareshgirProgramManager.Domain.UserAgg.Entities; +using Microsoft.EntityFrameworkCore; + +namespace GozareshgirProgramManager.Application._Common.Interfaces; + +public interface IProgramManagerDbContext +{ + DbSet Checkouts { set; get; } + DbSet SalaryPaymentSettings { set; get; } + DbSet Roles { get; set; } + DbSet Users { get; set; } + DbSet RefreshTokens { get; set; } + DbSet Customers { get; } + DbSet Projects { get; set; } + DbSet ProjectPhases { get; set; } + DbSet TaskSections { get; set; } + DbSet ProjectSections { get; set; } + DbSet PhaseSections { get; set; } + + DbSet ProjectTasks { get; set; } + + DbSet Skills { get; set; } + Task SaveChangesAsync(CancellationToken cancellationToken = default); +} + diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Models/AccessTokenResponse.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Models/AccessTokenResponse.cs new file mode 100644 index 00000000..3c4a68ec --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Models/AccessTokenResponse.cs @@ -0,0 +1,14 @@ +namespace GozareshgirProgramManager.Application._Common.Models; + +/// +/// پاسخ تازه‌سازی توکن دسترسی +/// +public class AccessTokenResponse +{ + public string AccessToken { get; set; } = string.Empty; + public DateTime ExpiresAt { get; set; } + public long UserId { get; set; } + public string FullName { get; set; } = string.Empty; + public string UserName { get; set; } = string.Empty; +} + diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Models/AuthViewModel.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Models/AuthViewModel.cs new file mode 100644 index 00000000..64de4d90 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Models/AuthViewModel.cs @@ -0,0 +1,11 @@ +namespace GozareshgirProgramManager.Application._Common.Models; + +/// +/// مدل ورودی برای احراز هویت +/// +public class AuthViewModel +{ + public long UserId { get; set; } +} + + diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Models/DomainEventNotification.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Models/DomainEventNotification.cs new file mode 100644 index 00000000..bf580abc --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Models/DomainEventNotification.cs @@ -0,0 +1,19 @@ +using GozareshgirProgramManager.Domain._Common; +using MediatR; + +namespace GozareshgirProgramManager.Application._Common.Models; + +/// +/// Wrapper to convert Domain Events to MediatR Notifications +/// +public class DomainEventNotification : INotification + where TDomainEvent : IDomainEvent +{ + public TDomainEvent DomainEvent { get; } + + public DomainEventNotification(TDomainEvent domainEvent) + { + DomainEvent = domainEvent; + } +} + diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Models/ErrorDetails.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Models/ErrorDetails.cs new file mode 100644 index 00000000..e69de29b diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Models/LoginResponse.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Models/LoginResponse.cs new file mode 100644 index 00000000..f4b98e4f --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Models/LoginResponse.cs @@ -0,0 +1,15 @@ +namespace GozareshgirProgramManager.Application._Common.Models; + +/// +/// پاسخ ورود به سیستم +/// +public class LoginResponse +{ + public string AccessToken { get; set; } = string.Empty; + public DateTime ExpiresAt { get; set; } + public long UserId { get; set; } + public string FullName { get; set; } = string.Empty; + public string UserName { get; set; } = string.Empty; + public List Roles { get; set; } = new(); +} + diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Models/OperationResult.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Models/OperationResult.cs new file mode 100644 index 00000000..324e9895 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Models/OperationResult.cs @@ -0,0 +1,60 @@ +namespace GozareshgirProgramManager.Application._Common.Models; + +public enum ErrorType +{ + None, + BadRequest, + NotFound, + Unauthorized, + Validation, + InternalServerError +} + +public class OperationResult +{ + public bool IsSuccess { get; private set; } + public string? ErrorMessage { get; private set; } + public List Errors { get; private set; } + public ErrorType ErrorType { get; private set; } + + protected OperationResult(bool isSuccess, string? errorMessage = null, List? errors = null, ErrorType errorType = ErrorType.None) + { + IsSuccess = isSuccess; + ErrorMessage = errorMessage; + Errors = errors ?? new List(); + ErrorType = errorType; + } + + public static OperationResult Success() => new(true); + public static OperationResult Failure(string errorMessage, ErrorType errorType = ErrorType.BadRequest) => new(false, errorMessage, errorType: errorType); + public static OperationResult Failure(List errors, ErrorType errorType = ErrorType.BadRequest) => new(false, errors: errors, errorType: errorType); + + // Helper methods for specific error types + public static OperationResult NotFound(string errorMessage) => new(false, errorMessage, errorType: ErrorType.NotFound); + public static OperationResult Unauthorized(string errorMessage) => new(false, errorMessage, errorType: ErrorType.Unauthorized); + public static OperationResult ValidationError(string errorMessage) => new(false, errorMessage, errorType: ErrorType.Validation); + public static OperationResult ValidationError(List errors) => new(false, errors: errors, errorType: ErrorType.Validation); + public static OperationResult InternalServerError(string errorMessage) => new(false, errorMessage, errorType: ErrorType.InternalServerError); +} + +public class OperationResult : OperationResult +{ + public T? Data { get; private set; } + + private OperationResult(bool isSuccess, T? data = default, string? errorMessage = null, List? errors = null, ErrorType errorType = ErrorType.None) + : base(isSuccess, errorMessage, errors, errorType) + { + Data = data; + } + + public static OperationResult Success(T data) => new(true, data); + public static new OperationResult Failure(string errorMessage, ErrorType errorType = ErrorType.BadRequest) => new(false, default, errorMessage, errorType: errorType); + public static new OperationResult Failure(List errors, ErrorType errorType = ErrorType.BadRequest) => new(false, default, errors: errors, errorType: errorType); + + // Helper methods for specific error types + public static new OperationResult NotFound(string errorMessage) => new(false, default, errorMessage, errorType: ErrorType.NotFound); + public static new OperationResult Unauthorized(string errorMessage) => new(false, default, errorMessage, errorType: ErrorType.Unauthorized); + public static new OperationResult ValidationError(string errorMessage) => new(false, default, errorMessage, errorType: ErrorType.Validation); + public static new OperationResult ValidationError(List errors) => new(false, default, errors: errors, errorType: ErrorType.Validation); + public static new OperationResult InternalServerError(string errorMessage) => new(false, default, errorMessage, errorType: ErrorType.InternalServerError); +} diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Models/PaginationRequest.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Models/PaginationRequest.cs new file mode 100644 index 00000000..6c55bae2 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Models/PaginationRequest.cs @@ -0,0 +1,8 @@ +namespace GozareshgirProgramManager.Application._Common.Models; + +public record PaginationRequest +{ + public int PageIndex { get; set; } = 1; + public int PageSize { get; set; } = 30; +} + diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Models/PaginationResult.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Models/PaginationResult.cs new file mode 100644 index 00000000..8249f241 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Models/PaginationResult.cs @@ -0,0 +1,11 @@ +namespace GozareshgirProgramManager.Application._Common.Models; + +public class PaginationResult +{ + public int TotalCount { get; set; } + public List List { get; set; } +} +public class PaginationResult:PaginationResult +{ + public TMeta? Meta { get; set; } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Models/TokenValidationResult.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Models/TokenValidationResult.cs new file mode 100644 index 00000000..37889e20 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/_Common/Models/TokenValidationResult.cs @@ -0,0 +1,24 @@ +namespace GozareshgirProgramManager.Application._Common.Models; + +/// +/// نتیجه اعتبارسنجی توکن +/// +public class TokenValidationResult +{ + public bool IsValid { get; set; } + public long? UserId { get; set; } + public string? ErrorMessage { get; set; } + + public static TokenValidationResult Success(long userId) => new() + { + IsValid = true, + UserId = userId + }; + + public static TokenValidationResult Failure(string errorMessage) => new() + { + IsValid = false, + ErrorMessage = errorMessage + }; +} + diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/CheckoutAgg/Entities/Checkout.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/CheckoutAgg/Entities/Checkout.cs new file mode 100644 index 00000000..22e4495e --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/CheckoutAgg/Entities/Checkout.cs @@ -0,0 +1,134 @@ +using System.ComponentModel.DataAnnotations.Schema; +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.CheckoutAgg.Enums; + +namespace GozareshgirProgramManager.Domain.CheckoutAgg.Entities; + +public class Checkout : EntityBase +{ + /// + /// ایجاد فیش + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public Checkout(DateTime checkoutStartDate, DateTime checkoutEndDate, int year, int month, string fullName, long userId, + int mandatoryHours, int totalHoursWorked, int totalDaysWorked, int remainingHours, double monthlySalaryDefined, double monthlySalaryPay, double deductionFromSalary) + { + CheckoutStartDate = checkoutStartDate; + CheckoutEndDate = checkoutEndDate; + Year = year; + Month = month; + FullName = fullName; + UserId = userId; + MandatoryHours = mandatoryHours; + TotalHoursWorked = totalHoursWorked; + TotalDaysWorked = totalDaysWorked; + RemainingHours = remainingHours; + MonthlySalaryDefined = monthlySalaryDefined; + MonthlySalaryPay = monthlySalaryPay; + DeductionFromSalary = deductionFromSalary; + + } + + /// + /// تاریخ شروع فیش حقوقی + /// + public DateTime CheckoutStartDate { get; private set; } + + /// + /// تاریخ پایان فیش حقوقی + /// + public DateTime CheckoutEndDate { get; private set; } + + /// + /// سال + /// + public int Year { get; private set; } + + /// + /// ماه + /// + public int Month { get; private set; } + + [NotMapped] + public string PersianMonthName=> Month.ToFarsiMonthByIntNumber(); + + /// + /// نام کامل کاربر + /// + public string FullName { get; private set; } + + /// + /// آی دی کاربر + /// + public long UserId { get; private set; } + + /// + /// ساعت موظفی + /// + public int MandatoryHours { get; private set; } + + /// + /// مجموع ساعات کارکرد پرسنل + /// + public int TotalHoursWorked { get; private set; } + + /// + /// مجمع روزهای کارکرد پرسنل + /// + public int TotalDaysWorked { get; private set; } + + /// + /// ساعات باقی مانده + /// کسر کار یا اضافه کار + /// + public int RemainingHours { get; private set; } + + /// + /// حقوق ماهانه + /// تعیین شده + /// + public double MonthlySalaryDefined { get; private set; } + + /// + /// حقوق نهایی که به پرسنل داده می شود + /// + public double MonthlySalaryPay { get; private set; } + + /// + /// کسر از حقوق + /// + public double DeductionFromSalary { get; private set; } + + /// + /// ویرایش فیش + /// + /// + /// + /// + /// + /// + /// + /// + public void Edit(int mandatoryHours, int totalHoursWorked, int totalDaysWorked, int remainingHours, double monthlySalaryDefined, double monthlySalaryPay, double deductionFromSalary) + { + MandatoryHours = mandatoryHours; + TotalHoursWorked = totalHoursWorked; + TotalDaysWorked = totalDaysWorked; + RemainingHours = remainingHours; + MonthlySalaryDefined = monthlySalaryDefined; + MonthlySalaryPay = monthlySalaryPay; + DeductionFromSalary = deductionFromSalary; + } +} \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/CheckoutAgg/Enums/CreateCheckoutStatus.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/CheckoutAgg/Enums/CreateCheckoutStatus.cs new file mode 100644 index 00000000..53b669b5 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/CheckoutAgg/Enums/CreateCheckoutStatus.cs @@ -0,0 +1,18 @@ +namespace GozareshgirProgramManager.Domain.CheckoutAgg.Enums; + +public enum CreateCheckoutStatus +{ + /// + /// آماده ایجاد + /// + ReadyToCreate = 1, + /// + /// قبلا ایجاد شده + /// + AlreadyCreated = 2, + /// + /// تنظیمات حقوق انجام نشده + /// + NotSetSalaryPaymentSettings = 3 + +} \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/CheckoutAgg/Enums/PersianMonthName.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/CheckoutAgg/Enums/PersianMonthName.cs new file mode 100644 index 00000000..0890604b --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/CheckoutAgg/Enums/PersianMonthName.cs @@ -0,0 +1,18 @@ +namespace GozareshgirProgramManager.Domain.CheckoutAgg.Enums; + +public enum PersianMonthName +{ + فروردین = 1, + اردیبهشت = 2, + خرداد = 3, + تیر = 4, + مرداد = 5, + شهریور = 6, + مهر = 7, + آبان = 8, + آذر = 9, + دی = 10, + بهمن = 11, + اسفند = 12, + +} \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/CheckoutAgg/Enums/TypeOfCheckoutHandler.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/CheckoutAgg/Enums/TypeOfCheckoutHandler.cs new file mode 100644 index 00000000..095562e7 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/CheckoutAgg/Enums/TypeOfCheckoutHandler.cs @@ -0,0 +1,22 @@ +namespace GozareshgirProgramManager.Domain.CheckoutAgg.Enums; + +/// +/// انتخاب حالت ایجاد یا ویراش تکی / گروهی +/// +public enum TypeOfCheckoutHandler +{ + /// + /// ایجاد گروهی + /// + CreateInGroup = 1, + + /// + /// ویرایش گروهی + /// + GroupEditing = 2, + + /// + /// ویرایش تکی + /// + SingleEdit = 3, +} \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/CheckoutAgg/Repositories/ICheckoutRepository.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/CheckoutAgg/Repositories/ICheckoutRepository.cs new file mode 100644 index 00000000..f33b9031 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/CheckoutAgg/Repositories/ICheckoutRepository.cs @@ -0,0 +1,9 @@ +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.CheckoutAgg.Entities; + +namespace GozareshgirProgramManager.Domain.CheckoutAgg.Repositories; + +public interface ICheckoutRepository : IRepository +{ + Task> GetCheckoutListByIds(List checkoutIds); +} \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/CustomerAgg/Customer.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/CustomerAgg/Customer.cs new file mode 100644 index 00000000..1126077b --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/CustomerAgg/Customer.cs @@ -0,0 +1,34 @@ +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.CustomerAgg.Events; + +namespace GozareshgirProgramManager.Domain.CustomerAgg; + +public class Customer : EntityBase, IAggregateRoot +{ + public string Name { get; private set; } + public string Email { get; private set; } + public DateTime CreatedAt { get; private set; } + + private Customer() { } // For EF Core + + private Customer(Guid id, string name, string email) + { + Id = id; + Name = name; + Email = email; + CreatedAt = DateTime.UtcNow; + } + + public static Customer Create(string name, string email) + { + var customer = new Customer(Guid.NewGuid(), name, email); + customer.AddDomainEvent(new CustomerRegistered(customer.Id, customer.Name, customer.Email)); + return customer; + } + + public void UpdateName(string name) + { + Name = name; + } +} + diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/CustomerAgg/Entities/Address.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/CustomerAgg/Entities/Address.cs new file mode 100644 index 00000000..e69de29b diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/CustomerAgg/Entities/Customer.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/CustomerAgg/Entities/Customer.cs new file mode 100644 index 00000000..e69de29b diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/CustomerAgg/Events/CustomerRegistered.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/CustomerAgg/Events/CustomerRegistered.cs new file mode 100644 index 00000000..2362f3fc --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/CustomerAgg/Events/CustomerRegistered.cs @@ -0,0 +1,12 @@ +using GozareshgirProgramManager.Domain._Common; + +namespace GozareshgirProgramManager.Domain.CustomerAgg.Events; + +public record CustomerRegistered( + Guid CustomerId, + string Name, + string Email) : IDomainEvent +{ + public DateTime OccurredOn { get; } = DateTime.UtcNow; +} + diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/CustomerAgg/Events/CustomerRegisteredEvent.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/CustomerAgg/Events/CustomerRegisteredEvent.cs new file mode 100644 index 00000000..e69de29b diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/CustomerAgg/Exceptions/CustomerNotFoundException.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/CustomerAgg/Exceptions/CustomerNotFoundException.cs new file mode 100644 index 00000000..b50831ad --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/CustomerAgg/Exceptions/CustomerNotFoundException.cs @@ -0,0 +1,10 @@ +namespace GozareshgirProgramManager.Domain.CustomerAgg.Exceptions; + +public class CustomerNotFoundException : Exception +{ + public CustomerNotFoundException(Guid customerId) + : base($"Customer with ID '{customerId}' was not found.") + { + } +} + diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/CustomerAgg/Exceptions/DuplicateEmailException.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/CustomerAgg/Exceptions/DuplicateEmailException.cs new file mode 100644 index 00000000..e69de29b diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/CustomerAgg/Repositories/ICustomerRepository.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/CustomerAgg/Repositories/ICustomerRepository.cs new file mode 100644 index 00000000..c0b0be7a --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/CustomerAgg/Repositories/ICustomerRepository.cs @@ -0,0 +1,10 @@ +namespace GozareshgirProgramManager.Domain.CustomerAgg.Repositories; + +public interface ICustomerRepository +{ + Task GetByIdAsync(Guid id, CancellationToken cancellationToken = default); + Task AddAsync(Customer customer, CancellationToken cancellationToken = default); + void Update(Customer customer); + void Delete(Customer customer); +} + diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/CustomerAgg/ValueObjects/Email.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/CustomerAgg/ValueObjects/Email.cs new file mode 100644 index 00000000..e69de29b diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/CustomerAgg/ValueObjects/PhoneNumber.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/CustomerAgg/ValueObjects/PhoneNumber.cs new file mode 100644 index 00000000..e69de29b diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/GozareshgirProgramManager.Domain.csproj b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/GozareshgirProgramManager.Domain.csproj new file mode 100644 index 00000000..9ae2365c --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/GozareshgirProgramManager.Domain.csproj @@ -0,0 +1,14 @@ + + + + net10.0 + enable + enable + + + + + + + + diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/HolidayAgg/Holiday.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/HolidayAgg/Holiday.cs new file mode 100644 index 00000000..fabc5c3a --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/HolidayAgg/Holiday.cs @@ -0,0 +1,25 @@ +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.HolidayItemAgg; + +namespace GozareshgirProgramManager.Domain.HolidayAgg; + +public class Holiday : EntityBase +{ + public Holiday(string year) + { + Year = year; + + } + + public string Year { get; private set; } + public List HolidayItems { get; set; } + + public Holiday() + { + HolidayItems = new List(); + } + public void Edit(string year) + { + Year = year; + } +} \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/HolidayItemAgg/HolidayItem.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/HolidayItemAgg/HolidayItem.cs new file mode 100644 index 00000000..3a66bd58 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/HolidayItemAgg/HolidayItem.cs @@ -0,0 +1,28 @@ +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.HolidayAgg; + +namespace GozareshgirProgramManager.Domain.HolidayItemAgg; + +public class HolidayItem : EntityBase +{ + public HolidayItem(DateTime holidaydate, long holidayId, string holidayYear) + { + Holidaydate = holidaydate; + HolidayId = holidayId; + HolidayYear = holidayYear; + } + + public DateTime Holidaydate { get; private set; } + public long HolidayId { get; private set; } + public string HolidayYear { get; private set; } + + public Holiday Holidayss { get; set; } + + public void Edit(DateTime holidaydate, long holidayId, string holidayYear) + { + Holidaydate = holidaydate; + HolidayId = holidayId; + HolidayYear = holidayYear; + + } +} \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/PermissionAgg/Entities/Permission.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/PermissionAgg/Entities/Permission.cs new file mode 100644 index 00000000..49e5cdc8 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/PermissionAgg/Entities/Permission.cs @@ -0,0 +1,21 @@ +using GozareshgirProgramManager.Domain.RoleAgg.Entities; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using GozareshgirProgramManager.Domain._Common; + +namespace GozareshgirProgramManager.Domain.PermissionAgg.Entities; + +public class Permission +{ + public long Id { get; private set; } + public int Code { get; private set; } + public Role Role { get; private set; } + + public Permission(int code) + { + Code = code; + } +} \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/PhaseSection.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/PhaseSection.cs new file mode 100644 index 00000000..33bdfcdf --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/PhaseSection.cs @@ -0,0 +1,41 @@ +using GozareshgirProgramManager.Domain._Common; + +namespace GozareshgirProgramManager.Domain.ProjectAgg.Entities; + +/// +/// بخش فاز - برای ذخیره تخصیص کاربر و مهارت در سطح Phase +/// +public class PhaseSection : EntityBase +{ + private PhaseSection() { } + + public PhaseSection(Guid phaseId, long userId, Guid skillId) + { + PhaseId = phaseId; + UserId = userId; + SkillId = skillId; + } + + public Guid PhaseId { get; private set; } + public long UserId { get; private set; } + public Guid SkillId { get; private set; } + + // Navigation property + public ProjectPhase Phase { get; private set; } = null!; + + public void UpdateUser(long userId) + { + UserId = userId; + } + + public void UpdateSkill(Guid skillId) + { + SkillId = skillId; + } + public void Update(long userId, Guid skillId) + { + UserId = userId; + SkillId = skillId; + } +} + diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Project.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Project.cs new file mode 100644 index 00000000..dc2bfa15 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/Project.cs @@ -0,0 +1,174 @@ +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.ProjectAgg.Enums; +using GozareshgirProgramManager.Domain.ProjectAgg.Events; + +namespace GozareshgirProgramManager.Domain.ProjectAgg.Entities; + +/// +/// پروژه - بالاترین سطح در سلسله مراتب و Aggregate Root +/// +public class Project : ProjectHierarchyNode +{ + private readonly List _phases; + private readonly List _projectSections; + + private Project() + { + _phases = new List(); + _projectSections = new List(); + } + + public Project(string name, string? description = null) : base(name, description) + { + _phases = new List(); + _projectSections = new List(); + AddDomainEvent(new ProjectCreatedEvent(Id, name)); + } + + + public IReadOnlyList Phases => _phases.AsReadOnly(); + public IReadOnlyList ProjectSections => _projectSections.AsReadOnly(); + + // Project-specific properties + public DateTime? StartDate { get; private set; } + public DateTime? EndDate { get; private set; } + public DateTime? PlannedStartDate { get; private set; } + public DateTime? PlannedEndDate { get; private set; } + public ProjectStatus Status { get; private set; } = ProjectStatus.Planning; + + + #region Phase Management + + public ProjectPhase AddPhase(string name, string? description = null) + { + var phase = new ProjectPhase(name, Id, description); + _phases.Add(phase); + AddDomainEvent(new PhaseAddedEvent(phase.Id, Id, name)); + return phase; + } + + public void RemovePhase(Guid phaseId) + { + var phase = _phases.FirstOrDefault(p => p.Id == phaseId); + if (phase == null) + throw new InvalidOperationException("فاز مورد نظر یافت نشد"); + + if (phase.Tasks.Any()) + throw new InvalidOperationException("نمی‌توان فازی را که شامل تسک است حذف کرد"); + + _phases.Remove(phase); + AddDomainEvent(new PhaseRemovedEvent(phaseId, Id)); + } + + #endregion + + #region ProjectSection Management + + public void AddProjectSection(long userId, Guid skillId) + { + var existingSection = _projectSections.FirstOrDefault(s => s.UserId == userId && s.SkillId == skillId); + if (existingSection == null) + { + var section = new ProjectSection(Id, userId, skillId); + _projectSections.Add(section); + } + } + + public void ClearProjectSections() + { + _projectSections.Clear(); + } + + #endregion + + #region Date Management + + public void SetDates(DateTime? startDate = null, DateTime? endDate = null) + { + if (startDate.HasValue && endDate.HasValue && startDate > endDate) + throw new ArgumentException("تاریخ شروع نمی‌تواند بعد از تاریخ پایان باشد"); + + StartDate = startDate; + EndDate = endDate; + } + + public void SetPlannedDates(DateTime? plannedStartDate = null, DateTime? plannedEndDate = null) + { + if (plannedStartDate.HasValue && plannedEndDate.HasValue && plannedStartDate > plannedEndDate) + throw new ArgumentException("تاریخ شروع برنامه‌ریزی شده نمی‌تواند بعد از تاریخ پایان برنامه‌ریزی شده باشد"); + + PlannedStartDate = plannedStartDate; + PlannedEndDate = plannedEndDate; + } + + public void UpdateStatus(ProjectStatus status) + { + Status = status; + AddDomainEvent(new ProjectStatusUpdatedEvent(Id, status)); + } + + #endregion + + #region Assignment Management + + public void AssignToUser(long userId, bool cascadeToPhases = true, bool forceOverride = false) + { + HasAssignmentOverride = true; + + if (cascadeToPhases) + { + foreach (var phase in _phases) + { + if (phase.HasAssignmentOverride && !forceOverride) + continue; + + phase.AssignToUser(userId, cascadeToTasks: true, forceOverride, markAsOverride: false); + } + } + + AddDomainEvent(new ProjectAssignedEvent(Id, userId)); + } + + public void Unassign(bool cascadeToPhases = true, bool forceOverride = false) + { + HasAssignmentOverride = true; + + if (cascadeToPhases) + { + foreach (var phase in _phases) + { + if (phase.HasAssignmentOverride && !forceOverride) + continue; + + phase.Unassign(cascadeToTasks: true, forceOverride, markAsOverride: false); + } + } + + AddDomainEvent(new ProjectUnassignedEvent(Id)); + } + + #endregion + + #region Time Calculation + + public override TimeSpan GetTotalTimeSpent() + { + return TimeSpan.FromTicks(_phases.Sum(p => p.GetTotalTimeSpent().Ticks)); + } + + public override TimeSpan GetTotalEstimatedTime() + { + return TimeSpan.FromTicks(_phases.Sum(p => p.GetTotalEstimatedTime().Ticks)); + } + + #endregion + + public void UpdateProjectSectionUser(Guid skillId, long userId) + { + var section = _projectSections.FirstOrDefault(s => s.SkillId == skillId); + if (section != null) + { + section.UpdateUser(userId); + } + } +} diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/ProjectHierarchyNode.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/ProjectHierarchyNode.cs new file mode 100644 index 00000000..51df2571 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/ProjectHierarchyNode.cs @@ -0,0 +1,78 @@ +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.ProjectAgg.Enums; + +namespace GozareshgirProgramManager.Domain.ProjectAgg.Entities; + +/// +/// کلاس پایه برای تمام نودهای سلسله مراتبی پروژه +/// +public abstract class ProjectHierarchyNode : EntityBase +{ + protected ProjectHierarchyNode() + { + } + + protected ProjectHierarchyNode(string name, string? description = null) + { + Name = name; + Description = description; + } + + public string Name { get; protected set; } = string.Empty; + public string? Description { get; protected set; } + + // Time allocation properties + public bool HasAssignmentOverride { get; protected set; } + + #region Update Methods + + public virtual void UpdateName(string name) + { + if (string.IsNullOrWhiteSpace(name)) + throw new ArgumentException("نام نمی‌تواند خالی باشد", nameof(name)); + + Name = name; + } + + public virtual void UpdateDescription(string? description) + { + Description = description; + } + + public void MarkAsOverridden() + { + HasAssignmentOverride = true; + } + + #endregion + + // #region Time Management + // + // public virtual void SetAllocatedTime(TimeSpan time, bool markAsOverride = true) + // { + // if (time < TimeSpan.Zero) + // throw new ArgumentException("زمان تخصیص‌یافته نمی‌تواند منفی باشد", nameof(time)); + // + // AllocatedTime = time; + // if (markAsOverride) + // { + // HasTimeOverride = true; + // } + // } + // + // public virtual void ClearTimeOverride() + // { + // HasTimeOverride = false; + // AllocatedTime = null; + // } + // + // #endregion + + #region Time Calculation (Abstract) + + public abstract TimeSpan GetTotalTimeSpent(); + public abstract TimeSpan GetTotalEstimatedTime(); + + #endregion +} + diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/ProjectPhase.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/ProjectPhase.cs new file mode 100644 index 00000000..539ac278 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/ProjectPhase.cs @@ -0,0 +1,199 @@ +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.ProjectAgg.Enums; +using GozareshgirProgramManager.Domain.ProjectAgg.Events; + +namespace GozareshgirProgramManager.Domain.ProjectAgg.Entities; + +/// +/// فاز پروژه - سطح میانی در سلسله مراتب +/// +public class ProjectPhase : ProjectHierarchyNode +{ + private readonly List _tasks; + private readonly List _phaseSections; + + private ProjectPhase() + { + _tasks = new List(); + _phaseSections = new List(); + } + + public ProjectPhase(string name, Guid projectId, string? description = null) : base(name, description) + { + ProjectId = projectId; + _tasks = new List(); + _phaseSections = new List(); + AddDomainEvent(new PhaseCreatedEvent(Id, projectId, name)); + } + + public Guid ProjectId { get; private set; } + public Project Project { get; private set; } = null!; + public IReadOnlyList Tasks => _tasks.AsReadOnly(); + public IReadOnlyList PhaseSections => _phaseSections.AsReadOnly(); + + // Phase-specific properties + public PhaseStatus Status { get; private set; } = PhaseStatus.Planning; + public DateTime? StartDate { get; private set; } + public DateTime? EndDate { get; private set; } + public int OrderIndex { get; private set; } + + #region Task Management + + public ProjectTask AddTask(string name, string? description = null) + { + var task = new ProjectTask(name, Id, description); + _tasks.Add(task); + AddDomainEvent(new TaskAddedEvent(task.Id, Id, name)); + return task; + } + + public void RemoveTask(Guid taskId) + { + var task = _tasks.FirstOrDefault(t => t.Id == taskId); + if (task == null) + throw new InvalidOperationException("تسک مورد نظر یافت نشد"); + + if (task.Sections.Any()) + throw new InvalidOperationException("نمی‌توان تسکی را که شامل بخش است حذف کرد"); + + _tasks.Remove(task); + AddDomainEvent(new TaskRemovedEvent(taskId, Id)); + } + + #endregion + + #region PhaseSection Management + + public void AddPhaseSection(long userId, Guid skillId) + { + var existingSection = _phaseSections.FirstOrDefault(s => s.UserId == userId && s.SkillId == skillId); + if (existingSection == null) + { + var section = new PhaseSection(Id, userId, skillId); + _phaseSections.Add(section); + } + + } + + public void RemovePhaseSection(long userId, Guid skillId) + { + var section = _phaseSections.FirstOrDefault(s => s.UserId == userId && s.SkillId == skillId); + if (section != null) + { + _phaseSections.Remove(section); + } + } + + public void ClearPhaseSections() + { + _phaseSections.Clear(); + } + + #endregion + + #region Status Management + + public void UpdateStatus(PhaseStatus status) + { + Status = status; + AddDomainEvent(new PhaseStatusUpdatedEvent(Id, status)); + } + + public void SetDates(DateTime? startDate = null, DateTime? endDate = null) + { + if (startDate.HasValue && endDate.HasValue && startDate > endDate) + throw new ArgumentException("تاریخ شروع نمی‌تواند بعد از تاریخ پایان باشد"); + + StartDate = startDate; + EndDate = endDate; + } + + public void SetOrderIndex(int orderIndex) + { + if (orderIndex < 0) + throw new ArgumentException("ترتیب نمی‌تواند منفی باشد", nameof(orderIndex)); + + OrderIndex = orderIndex; + } + + #endregion + + #region Assignment Management + + public void AssignToUser(long userId, bool cascadeToTasks = true, bool forceOverride = false, bool markAsOverride = true) + { + if (markAsOverride) + { + HasAssignmentOverride = true; + } + + if (cascadeToTasks) + { + foreach (var task in _tasks) + { + if (task.HasAssignmentOverride && !forceOverride) + continue; + + task.AssignToUser(userId, cascadeToSections: true, forceOverride, markAsOverride: false); + } + } + + AddDomainEvent(new PhaseAssignedEvent(Id, userId)); + } + + public void Unassign(bool cascadeToTasks = true, bool forceOverride = false, bool markAsOverride = true) + { + if (markAsOverride) + { + HasAssignmentOverride = true; + } + + if (cascadeToTasks) + { + foreach (var task in _tasks) + { + if (task.HasAssignmentOverride && !forceOverride) + continue; + + task.Unassign(cascadeToSections: true, forceOverride, markAsOverride: false); + } + } + + AddDomainEvent(new PhaseUnassignedEvent(Id)); + } + + #endregion + + #region Time Calculation + + public override TimeSpan GetTotalTimeSpent() + { + return TimeSpan.FromTicks(_tasks.Sum(t => t.GetTotalTimeSpent().Ticks)); + } + + public override TimeSpan GetTotalEstimatedTime() + { + return TimeSpan.FromTicks(_tasks.Sum(t => t.GetTotalEstimatedTime().Ticks)); + } + + #endregion + + #region Query Helpers + + public IEnumerable GetTasksWithTimeOverride() + { + return _tasks.Where(t => t.HasTimeOverride); + } + + public IEnumerable GetTasksWithAssignmentOverride() + { + return _tasks.Where(t => t.HasAssignmentOverride); + } + + public IEnumerable GetAllSections() + { + return _tasks.SelectMany(t => t.Sections); + } + + #endregion +} diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/ProjectSection.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/ProjectSection.cs new file mode 100644 index 00000000..67820d49 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/ProjectSection.cs @@ -0,0 +1,34 @@ +using GozareshgirProgramManager.Domain._Common; + +namespace GozareshgirProgramManager.Domain.ProjectAgg.Entities; + +/// +/// ProjectSection: shortcut container for UserId + SkillId at Project level +/// +public class ProjectSection : EntityBase +{ + private ProjectSection() { } + + public ProjectSection(Guid projectId, long userId, Guid skillId) + { + ProjectId = projectId; + UserId = userId; + SkillId = skillId; + } + + public Guid ProjectId { get; private set; } + public long UserId { get; private set; } + public Guid SkillId { get; private set; } + + public Project Project { get; private set; } = null!; + + public void UpdateUser(long userId) + { + UserId = userId; + } + + public void UpdateSkill(Guid skillId) + { + SkillId = skillId; + } +} diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/ProjectTask.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/ProjectTask.cs new file mode 100644 index 00000000..863e332f --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/ProjectTask.cs @@ -0,0 +1,249 @@ +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.ProjectAgg.Enums; +using GozareshgirProgramManager.Domain.ProjectAgg.Events; + +namespace GozareshgirProgramManager.Domain.ProjectAgg.Entities; + +/// +/// تسک - پایین‌ترین سطح در سلسله مراتب که شامل بخش‌ها می‌شود +/// +public class ProjectTask : ProjectHierarchyNode +{ + private readonly List _sections; + + private ProjectTask() + { + _sections = new List(); + } + + public ProjectTask(string name, Guid phaseId, string? description = null) : base(name, description) + { + PhaseId = phaseId; + _sections = new List(); + Priority = TaskPriority.Medium; + AddDomainEvent(new TaskCreatedEvent(Id, phaseId, name)); + } + + public Guid PhaseId { get; private set; } + public ProjectPhase Phase { get; private set; } = null!; + public IReadOnlyList Sections => _sections.AsReadOnly(); + + // Task-specific properties + public Enums.TaskStatus Status { get; private set; } = Enums.TaskStatus.NotStarted; + public TaskPriority Priority { get; private set; } + public DateTime? StartDate { get; private set; } + public DateTime? EndDate { get; private set; } + public DateTime? DueDate { get; private set; } + public int OrderIndex { get; private set; } + public TimeSpan? AllocatedTime { get; protected set; } + public bool HasTimeOverride { get; protected set; } + + #region Section Management + + public void AddSection(TaskSection section, bool cascadeToChildren = false) + { + var existingSection = _sections.FirstOrDefault(s => s.SkillId == section.SkillId); + if (existingSection != null) + { + // اگر userId متفاوت است، ویرایش شود + if (existingSection.CurrentAssignedUserId != section.CurrentAssignedUserId) + { + if (existingSection.CurrentAssignedUserId > 0) + { + existingSection.TransferToUser(existingSection.CurrentAssignedUserId, section.CurrentAssignedUserId); + } + else + { + existingSection.AssignToUser(section.CurrentAssignedUserId); + } + } + } + else + { + _sections.Add(section); + AddDomainEvent(new TaskSectionAddedEvent(Id, section.Id, section.SkillId)); + } + } + + public void AddSection(Guid skillId, long assignedUserId) + { + var existingSection = _sections.FirstOrDefault(s => s.SkillId == skillId); + if (existingSection != null) + { + if (existingSection.CurrentAssignedUserId != assignedUserId) + { + if (existingSection.CurrentAssignedUserId > 0) + { + existingSection.TransferToUser(existingSection.CurrentAssignedUserId, assignedUserId); + } + else + { + existingSection.AssignToUser(assignedUserId); + } + } + return; + } + + var section = new TaskSection(Id, skillId, assignedUserId); + _sections.Add(section); + AddDomainEvent(new TaskSectionAddedEvent(Id, section.Id, skillId)); + } + + public void RemoveSection(Guid sectionId) + { + var section = _sections.FirstOrDefault(s => s.Id == sectionId); + if (section == null) + throw new InvalidOperationException("بخش مورد نظر یافت نشد"); + + _sections.Remove(section); + AddDomainEvent(new TaskSectionRemovedEvent(Id, sectionId)); + } + + public void RemoveSectionBySkill(Guid skillId) + { + var section = _sections.FirstOrDefault(s => s.SkillId == skillId); + if (section != null) + { + _sections.Remove(section); + AddDomainEvent(new TaskSectionRemovedEvent(Id, section.Id)); + } + } + + #endregion + + #region Status Management + + public void UpdateStatus(Enums.TaskStatus status) + { + Status = status; + AddDomainEvent(new TaskStatusUpdatedEvent(Id, status)); + } + + public void SetPriority(TaskPriority priority) + { + Priority = priority; + AddDomainEvent(new TaskPriorityUpdatedEvent(Id, priority)); + } + + public void SetDates(DateTime? startDate = null, DateTime? endDate = null, DateTime? dueDate = null) + { + if (startDate.HasValue && endDate.HasValue && startDate > endDate) + throw new ArgumentException("تاریخ شروع نمی‌تواند بعد از تاریخ پایان باشد"); + + if (dueDate.HasValue && endDate.HasValue && dueDate < endDate) + throw new ArgumentException("تاریخ مهلت نمی‌تواند قبل از تاریخ پایان باشد"); + + StartDate = startDate; + EndDate = endDate; + DueDate = dueDate; + } + + public void SetOrderIndex(int orderIndex) + { + if (orderIndex < 0) + throw new ArgumentException("ترتیب نمی‌تواند منفی باشد", nameof(orderIndex)); + + OrderIndex = orderIndex; + } + + #endregion + + #region Assignment Management + + public void AssignToUser(long userId, bool cascadeToSections = true, bool forceOverride = false, bool markAsOverride = true) + { + if (markAsOverride) + { + HasAssignmentOverride = true; + } + + if (cascadeToSections) + { + foreach (var section in _sections) + { + section.AssignToUser(userId); + } + } + + AddDomainEvent(new TaskAssignedEvent(Id, userId)); + } + + public void Unassign(bool cascadeToSections = true, bool forceOverride = false, bool markAsOverride = true) + { + if (markAsOverride) + { + HasAssignmentOverride = true; + } + + if (cascadeToSections) + { + foreach (var section in _sections) + { + section.Unassign(); + } + } + + AddDomainEvent(new TaskUnassignedEvent(Id)); + } + + #endregion + + #region Time Calculation + + public override TimeSpan GetTotalTimeSpent() + { + return TimeSpan.FromTicks(_sections.Sum(s => s.GetTotalTimeSpent().Ticks)); + } + + public override TimeSpan GetTotalEstimatedTime() + { + return TimeSpan.FromTicks(_sections.Sum(s => s.EstimatedHours.Ticks)); + } + + #endregion + + #region Query Helpers + + public IEnumerable GetSectionsBySkill(Guid skillId) + { + return _sections.Where(s => s.SkillId == skillId); + } + + public TaskSection? GetSectionBySkill(Guid skillId) + { + return _sections.FirstOrDefault(s => s.SkillId == skillId); + } + + public bool HasSection(Guid skillId) + { + return _sections.Any(s => s.SkillId == skillId); + } + + public IEnumerable GetAssignedSections(long userId) + { + return _sections.Where(s => s.CurrentAssignedUserId == userId); + } + + #endregion + #region Time Management + + public void SetAllocatedTime(TimeSpan time, bool markAsOverride = true) + { + if (time < TimeSpan.Zero) + throw new ArgumentException("زمان تخصیص‌یافته نمی‌تواند منفی باشد", nameof(time)); + + AllocatedTime = time; + if (markAsOverride) + { + HasTimeOverride = true; + } + } + + public void ClearTimeOverride() + { + HasTimeOverride = false; + AllocatedTime = null; + } + + #endregion +} diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSection.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSection.cs new file mode 100644 index 00000000..e478478d --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSection.cs @@ -0,0 +1,223 @@ +using System.Linq; +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain._Common.Exceptions; +using GozareshgirProgramManager.Domain.ProjectAgg.Enums; +using GozareshgirProgramManager.Domain.ProjectAgg.Events; +using GozareshgirProgramManager.Domain.ProjectAgg.Models; +using GozareshgirProgramManager.Domain.SkillAgg.Entities; + +namespace GozareshgirProgramManager.Domain.ProjectAgg.Entities; + +/// +/// بخش تسک - برای ذخیره کار واقعی که کاربر روی یک مهارت خاص انجام می‌دهد +/// +public class TaskSection : EntityBase +{ + private readonly List _activities; + private readonly List _additionalTimes; + + private TaskSection() + { + _activities = new List(); + _additionalTimes = new List(); + } + + public TaskSection(Guid taskId, Guid skillId, long currentAssignedUserId) + { + TaskId = taskId; + SkillId = skillId; + CurrentAssignedUserId = currentAssignedUserId; + OriginalAssignedUserId = currentAssignedUserId; + InitialEstimatedHours = TimeSpan.Zero; + _activities = new List(); + _additionalTimes = new List(); + Status = TaskSectionStatus.ReadyToStart; + AddDomainEvent(new TaskSectionAddedEvent(taskId, Id, skillId)); + } + + public Guid TaskId { get; private set; } + public Guid SkillId { get; private set; } + public TimeSpan InitialEstimatedHours { get; private set; } + public string? InitialDescription { get; set; } + public TaskSectionStatus Status { get; private set; } + + // شخصی که برای اولین بار این بخش به او اختصاص داده شده (مالک اصلی) + public long OriginalAssignedUserId { get; private set; } + + // شخصی که در حال حاضر این بخش به او اختصاص داده شده + public long CurrentAssignedUserId { get; private set; } + + // Navigation to ProjectTask (must be Task level) + public ProjectTask Task { get; private set; } = null!; + public Skill? Skill { get; set; } + + public IReadOnlyList Activities => _activities.AsReadOnly(); + public IReadOnlyList AdditionalTimes => _additionalTimes.AsReadOnly(); + + // محاسبه تایم نهایی (اولیه + تمام اضافه‌ها) + public TimeSpan FinalEstimatedHours => + TimeSpan.FromTicks(InitialEstimatedHours.Ticks + _additionalTimes.Sum(at => at.Hours.Ticks)); + + // برای backward compatibility + public TimeSpan EstimatedHours => FinalEstimatedHours; + + public void AddAdditionalTime(TimeSpan additionalHours, string? reason = null, long? addedByUserId = null) + { + if (additionalHours <= TimeSpan.Zero) + throw new BadRequestException("تایم اضافی باید بزرگتر از صفر باشد", nameof(additionalHours)); + + var additionalTime = new TaskSectionAdditionalTime(additionalHours, reason, addedByUserId); + _additionalTimes.Add(additionalTime); + } + + public void UpdateInitialEstimatedHours(TimeSpan newInitialEstimate, string initialDescription) + { + if (newInitialEstimate <= TimeSpan.Zero) + throw new BadRequestException("تایم تخمینی اولیه باید بزرگتر از صفر باشد", nameof(newInitialEstimate)); + + InitialEstimatedHours = newInitialEstimate; + InitialDescription = initialDescription; + } + + public void RemoveAdditionalTime(Guid additionalTimeId) + { + var additionalTime = _additionalTimes.FirstOrDefault(at => at.Id == additionalTimeId); + if (additionalTime == null) + throw new BadRequestException("تایم اضافی مورد نظر یافت نشد"); + + _additionalTimes.Remove(additionalTime); + } + + public TimeSpan GetTotalAdditionalTime() + { + return TimeSpan.FromTicks(_additionalTimes.Sum(at => at.Hours.Ticks)); + } + + public void UnassignUser() + { + if (_activities.Any(a => a.IsActive)) + { + throw new BadRequestException("نمی‌توان کاربری را که در حال کار است حذف کرد"); + } + + CurrentAssignedUserId = 0; + UpdateStatus(TaskSectionStatus.NotAssigned); + } + + public void StartWork(long userId, string? notes = null) + { + if (CurrentAssignedUserId != userId) + { + throw new BadRequestException("کاربر مجاز به شروع این بخش نیست"); + } + + // if (Status == TaskSectionStatus.Completed) + // { + // throw new BadRequestException("این بخش قبلاً تکمیل شده است"); + // } + + if (_activities.Any(a => a.IsActive)) + { + throw new BadRequestException("یک فعالیت در حال انجام وجود دارد"); + } + + var activity = new TaskSectionActivity(Id, userId, notes); + _activities.Add(activity); + + + UpdateStatus(TaskSectionStatus.InProgress); + } + + public void StopWork(long userId, TaskSectionStatus taskSectionStatus, string? endNotes = null) + { + var activeActivity = _activities.FirstOrDefault(a => a.IsActive); + if (activeActivity == null) + { + throw new BadRequestException("هیچ فعالیت فعالی یافت نشد"); + } + + if (activeActivity.UserId != userId) + { + throw new BadRequestException("کاربر مجاز به توقف این فعالیت نیست"); + } + + UpdateStatus(taskSectionStatus); + activeActivity.StopWork(endNotes); + } + + public void CompleteSection() + { + if (_activities.Any(a => a.IsActive)) + { + throw new BadRequestException("نمی‌توان بخشی را که فعالیت فعال دارد تکمیل کرد"); + } + + UpdateStatus(TaskSectionStatus.Completed); + } + + public void UpdateStatus(TaskSectionStatus status) + { + var oldStatus = Status; + Status = status; + AddDomainEvent(new TaskSectionStatusChangedEvent(Id, oldStatus, status)); + } + + public TimeSpan GetTotalTimeSpent() + { + return TimeSpan.FromTicks(_activities.Sum(a => a.GetTimeSpent().Ticks)); + } + + public bool IsCompleted() + { + return Status == TaskSectionStatus.Completed; + } + + public bool IsInProgress() + { + return _activities.Any(a => a.IsActive); + } + + public void AssignToUser(long userId) + { + if (OriginalAssignedUserId == 0) + { + OriginalAssignedUserId = userId; + } + + CurrentAssignedUserId = userId; + + if (Status == TaskSectionStatus.NotAssigned) + { + UpdateStatus(TaskSectionStatus.ReadyToStart); + } + + AddDomainEvent(new TaskSectionAssignedEvent(Id, userId)); + } + + public void TransferToUser(long fromUserId, long toUserId) + { + if (CurrentAssignedUserId != fromUserId) + { + throw new BadRequestException("کاربر فعلی با کاربر منبع مطابقت ندارد"); + } + + if (_activities.Any(a => a.IsActive)) + { + throw new BadRequestException("نمی‌توان بخشی را که در حال انجام است انتقال داد"); + } + + OriginalAssignedUserId = toUserId; + CurrentAssignedUserId = toUserId; + AddDomainEvent(new TaskSectionTransferredEvent(Id, fromUserId, toUserId)); + } + + public void Unassign() + { + UnassignUser(); + } + + public void ClearAdditionalTimes() + { + _additionalTimes.Clear(); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSectionActivity.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSectionActivity.cs new file mode 100644 index 00000000..85e60d0d --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSectionActivity.cs @@ -0,0 +1,57 @@ +using System.Diagnostics.CodeAnalysis; +using GozareshgirProgramManager.Domain._Common; + +namespace GozareshgirProgramManager.Domain.ProjectAgg.Entities; + +/// +/// فعالیت کاری روی یک بخش +/// +public class TaskSectionActivity : EntityBase +{ + private TaskSectionActivity() { } + + public TaskSectionActivity(Guid sectionId, long userId, string? notes = null) + { + SectionId = sectionId; + UserId = userId; + StartDate = DateTime.Now; + Notes = notes; + IsActive = true; + } + + public Guid SectionId { get; private set; } + public long UserId { get; private set; } + public DateTime StartDate { get; private set; } + public DateTime? EndDate { get; private set; } + public string? Notes { get; private set; } + public string? EndNotes { get; private set; } + public bool IsActive { get; private set; } + + // Navigation property + public TaskSection Section { get; private set; } = null!; + + public void StopWork(string? endNotes = null) + { + if (!IsActive) + throw new InvalidOperationException("این فعالیت قبلاً متوقف شده است."); + + EndDate = DateTime.Now; + EndNotes = endNotes; + IsActive = false; + } + + public TimeSpan GetTimeSpent() + { + if (IsActive) + { + return DateTime.Now - StartDate; + } + + return (EndDate ?? DateTime.Now) - StartDate; + } + + public void UpdateNotes(string? notes) + { + Notes = notes; + } +} diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSectionAdditionalTime.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSectionAdditionalTime.cs new file mode 100644 index 00000000..657f76cc --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/TaskSectionAdditionalTime.cs @@ -0,0 +1,29 @@ +using GozareshgirProgramManager.Domain._Common; + +namespace GozareshgirProgramManager.Domain.ProjectAgg.Entities; + +/// +/// زمان اضافی اضافه شده بعد از تخمین اولیه +/// +public class TaskSectionAdditionalTime : EntityBase +{ + private TaskSectionAdditionalTime() { } + + public TaskSectionAdditionalTime(TimeSpan hours, string? reason = null, long? addedByUserId = null) + { + Hours = hours; + Reason = reason; + AddedByUserId = addedByUserId; + AddedAt = DateTime.UtcNow; + } + + public TimeSpan Hours { get; private set; } + public string? Reason { get; private set; } + public long? AddedByUserId { get; private set; } + public DateTime AddedAt { get; private set; } + + public void UpdateReason(string? reason) + { + Reason = reason; + } +} diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/UserTimeReport.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/UserTimeReport.cs new file mode 100644 index 00000000..d3525513 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/UserTimeReport.cs @@ -0,0 +1,18 @@ +namespace GozareshgirProgramManager.Domain.ProjectAgg.Entities; + +public class UserTimeReport +{ + public long UserId { get; set; } + public string UserName { get; set; } = string.Empty; + public TimeSpan TotalTimeSpent { get; set; } + public TimeSpan EstimatedTime { get; set; } + public int ActivityCount { get; set; } + public DateTime LastActivity { get; set; } + public DateTime? FirstActivity { get; set; } + public double EfficiencyRate => EstimatedTime.TotalHours > 0 ? + (EstimatedTime.TotalHours / TotalTimeSpent.TotalHours) * 100 : 0; + + public bool IsOvertime => TotalTimeSpent > EstimatedTime; + + public TimeSpan TimeDifference => TotalTimeSpent - EstimatedTime; +} \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Enums/PhaseStatus.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Enums/PhaseStatus.cs new file mode 100644 index 00000000..a2aa534c --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Enums/PhaseStatus.cs @@ -0,0 +1,37 @@ +namespace GozareshgirProgramManager.Domain.ProjectAgg.Enums; + +/// +/// وضعیت فاز پروژه +/// +public enum PhaseStatus +{ + /// + /// در حال برنامه‌ریزی + /// + Planning = 0, + + /// + /// آماده شروع + /// + Ready = 1, + + /// + /// در حال اجرا + /// + InProgress = 2, + + /// + /// متوقف شده + /// + OnHold = 3, + + /// + /// تکمیل شده + /// + Completed = 4, + + /// + /// لغو شده + /// + Cancelled = 5 +} diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Enums/ProjectHierarchyLevel.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Enums/ProjectHierarchyLevel.cs new file mode 100644 index 00000000..f5a2eb28 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Enums/ProjectHierarchyLevel.cs @@ -0,0 +1,23 @@ +namespace GozareshgirProgramManager.Domain.ProjectAgg.Enums; + +/// +/// سطوح مختلف در سلسله مراتب پروژه +/// +public enum ProjectHierarchyLevel +{ + /// + /// سطح پروژه (بالاترین سطح) + /// + Project = 0, + + /// + /// سطح فاز پروژه + /// + Phase = 1, + + /// + /// سطح تسک + /// + Task = 2, +} + diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Enums/ProjectStatus.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Enums/ProjectStatus.cs new file mode 100644 index 00000000..fbd58771 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Enums/ProjectStatus.cs @@ -0,0 +1,37 @@ +namespace GozareshgirProgramManager.Domain.ProjectAgg.Enums; + +/// +/// وضعیت پروژه +/// +public enum ProjectStatus +{ + /// + /// در حال برنامه‌ریزی + /// + Planning = 0, + + /// + /// آماده شروع + /// + Ready = 1, + + /// + /// در حال اجرا + /// + InProgress = 2, + + /// + /// متوقف شده + /// + OnHold = 3, + + /// + /// تکمیل شده + /// + Completed = 4, + + /// + /// لغو شده + /// + Cancelled = 5 +} diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Enums/TaskPriority.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Enums/TaskPriority.cs new file mode 100644 index 00000000..13ccd784 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Enums/TaskPriority.cs @@ -0,0 +1,27 @@ +namespace GozareshgirProgramManager.Domain.ProjectAgg.Enums; + +/// +/// اولویت تسک +/// +public enum TaskPriority +{ + /// + /// پایین + /// + Low = 0, + + /// + /// متوسط + /// + Medium = 1, + + /// + /// بالا + /// + High = 2, + + /// + /// بحرانی + /// + Critical = 3 +} diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Enums/TaskSectionStatus.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Enums/TaskSectionStatus.cs new file mode 100644 index 00000000..d5208bfb --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Enums/TaskSectionStatus.cs @@ -0,0 +1,10 @@ +namespace GozareshgirProgramManager.Domain.ProjectAgg.Enums; + +public enum TaskSectionStatus +{ + NotAssigned = 0, // تخصیص داده نشده + ReadyToStart = 1, // آماده شروع + InProgress = 2, // درحال انجام + Incomplete = 3, // ناتمام شده + Completed = 4 // تکمیل شده +} \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Enums/TaskStatus.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Enums/TaskStatus.cs new file mode 100644 index 00000000..fc0d3c20 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Enums/TaskStatus.cs @@ -0,0 +1,9 @@ +namespace GozareshgirProgramManager.Domain.ProjectAgg.Enums; + +public enum TaskStatus +{ + NotStarted = 1, + InProgress = 2, + Completed = 3, + OnHold = 4 +} \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Events/ProjectEvents.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Events/ProjectEvents.cs new file mode 100644 index 00000000..e823967e --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Events/ProjectEvents.cs @@ -0,0 +1,177 @@ +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Enums; +using TaskStatus = GozareshgirProgramManager.Domain.ProjectAgg.Enums.TaskStatus; + +namespace GozareshgirProgramManager.Domain.ProjectAgg.Events; + +// Project Events +public record ProjectCreatedEvent(Guid ProjectId, string Name) : IDomainEvent +{ + public DateTime OccurredOn { get; init; } = DateTime.UtcNow; +} + +public record ProjectStatusUpdatedEvent(Guid ProjectId, ProjectStatus Status) : IDomainEvent +{ + public DateTime OccurredOn { get; init; } = DateTime.UtcNow; +} + +public record ProjectAssignedEvent(Guid ProjectId, long UserId) : IDomainEvent +{ + public DateTime OccurredOn { get; init; } = DateTime.UtcNow; +} + +public record ProjectUnassignedEvent(Guid ProjectId) : IDomainEvent +{ + public DateTime OccurredOn { get; init; } = DateTime.UtcNow; +} + +// Phase Events +public record PhaseCreatedEvent(Guid PhaseId, Guid ProjectId, string Name) : IDomainEvent +{ + public DateTime OccurredOn { get; init; } = DateTime.UtcNow; +} + +public record PhaseAddedEvent(Guid PhaseId, Guid ProjectId, string Name) : IDomainEvent +{ + public DateTime OccurredOn { get; init; } = DateTime.UtcNow; +} + +public record PhaseRemovedEvent(Guid PhaseId, Guid ProjectId) : IDomainEvent +{ + public DateTime OccurredOn { get; init; } = DateTime.UtcNow; +} + +public record PhaseStatusUpdatedEvent(Guid PhaseId, PhaseStatus Status) : IDomainEvent +{ + public DateTime OccurredOn { get; init; } = DateTime.UtcNow; +} + +public record PhaseAssignedEvent(Guid PhaseId, long UserId) : IDomainEvent +{ + public DateTime OccurredOn { get; init; } = DateTime.UtcNow; +} + +public record PhaseUnassignedEvent(Guid PhaseId) : IDomainEvent +{ + public DateTime OccurredOn { get; init; } = DateTime.UtcNow; +} + +// Task Events +public record TaskCreatedEvent(Guid TaskId, Guid PhaseId, string Name) : IDomainEvent +{ + public DateTime OccurredOn { get; init; } = DateTime.UtcNow; +} + +public record TaskAddedEvent(Guid TaskId, Guid PhaseId, string Name) : IDomainEvent +{ + public DateTime OccurredOn { get; init; } = DateTime.UtcNow; +} + +public record TaskRemovedEvent(Guid TaskId, Guid PhaseId) : IDomainEvent +{ + public DateTime OccurredOn { get; init; } = DateTime.UtcNow; +} + +public record TaskStatusUpdatedEvent(Guid TaskId, TaskStatus Status) : IDomainEvent +{ + public DateTime OccurredOn { get; init; } = DateTime.UtcNow; +} + +public record TaskPriorityUpdatedEvent(Guid TaskId, TaskPriority Priority) : IDomainEvent +{ + public DateTime OccurredOn { get; init; } = DateTime.UtcNow; +} + +public record TaskAssignedEvent(Guid TaskId, long UserId) : IDomainEvent +{ + public DateTime OccurredOn { get; init; } = DateTime.UtcNow; +} + +public record TaskUnassignedEvent(Guid TaskId) : IDomainEvent +{ + public DateTime OccurredOn { get; init; } = DateTime.UtcNow; +} + +public record TaskSectionAddedEvent(Guid TaskId, Guid SectionId, Guid SkillId) : IDomainEvent +{ + public DateTime OccurredOn { get; init; } = DateTime.UtcNow; +} + +public record TaskSectionRemovedEvent(Guid TaskId, Guid SectionId) : IDomainEvent +{ + public DateTime OccurredOn { get; init; } = DateTime.UtcNow; +} + +// TaskSection Events +public record TaskSectionStatusChangedEvent(Guid SectionId, TaskSectionStatus OldStatus, TaskSectionStatus NewStatus) : IDomainEvent +{ + public DateTime OccurredOn { get; init; } = DateTime.UtcNow; +} + +public record TaskSectionAssignedEvent(Guid SectionId, long UserId) : IDomainEvent +{ + public DateTime OccurredOn { get; init; } = DateTime.UtcNow; +} + +public record TaskSectionTransferredEvent(Guid SectionId, long FromUserId, long ToUserId) : IDomainEvent +{ + public DateTime OccurredOn { get; init; } = DateTime.UtcNow; +} + +// 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 record ProjectTaskStatusChangedEvent(Guid SectionId, TaskStatus OldStatus, TaskStatus NewStatus) : IDomainEvent +{ + public DateTime OccurredOn { get; init; } = DateTime.UtcNow; +} + +public record ProjectSectionAddedEvent(Guid SectionId, Guid TaskId) : IDomainEvent +{ + public DateTime OccurredOn { get; init; } = DateTime.UtcNow; +} + + +public record ProjectSectionAssignedEvent(Guid SectionId, long UserId) : IDomainEvent +{ + public DateTime OccurredOn { get; init; } = DateTime.UtcNow; +} + +public record ProjectSectionTransferredEvent(Guid SectionId, long FromUserId, long ToUserId) : IDomainEvent +{ + public DateTime OccurredOn { get; init; } = DateTime.UtcNow; +} + +public record WorkStartedEvent(Guid SectionId, long UserId, DateTime StartTime, string? Notes) : IDomainEvent +{ + public DateTime OccurredOn { get; init; } = DateTime.UtcNow; +} + +public record WorkStoppedEvent(Guid SectionId, long UserId, DateTime StartTime, DateTime EndTime, TimeSpan Duration, string? Notes) : IDomainEvent +{ + public DateTime OccurredOn { get; init; } = DateTime.UtcNow; +} + +public record ProjectSectionCompletedEvent(Guid ProjectId, long UserId, TimeSpan TotalTimeSpent, string? Notes) : IDomainEvent +{ + public DateTime OccurredOn { get; init; } = DateTime.UtcNow; +} + +public record AdditionalTimeAddedEvent(Guid ProjectId, Guid AdditionalTimeId, TimeSpan Hours, string? Reason, long? AddedByUserId) : IDomainEvent +{ + public DateTime OccurredOn { get; init; } = DateTime.UtcNow; +} + +public record AdditionalTimeRemovedEvent(Guid ProjectId, Guid AdditionalTimeId, TimeSpan RemovedHours) : IDomainEvent +{ + public DateTime OccurredOn { get; init; } = DateTime.UtcNow; +} + +public record InitialEstimatedTimeUpdatedEvent(Guid ProjectId, TimeSpan OldEstimate, TimeSpan NewEstimate) : IDomainEvent +{ + public DateTime OccurredOn { get; init; } = DateTime.UtcNow; +} diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Models/UserTimeReport.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Models/UserTimeReport.cs new file mode 100644 index 00000000..c02c1a39 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Models/UserTimeReport.cs @@ -0,0 +1,12 @@ +namespace GozareshgirProgramManager.Domain.ProjectAgg.Models; + +/// +/// گزارش زمان کاربر برای یک بخش پروژه +/// +public class UserTimeReport +{ + public long UserId { get; set; } + public TimeSpan TotalTimeSpent { get; set; } + public int ActivityCount { get; set; } + public DateTime LastActivity { get; set; } +} diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/IPhaseSectionRepository.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/IPhaseSectionRepository.cs new file mode 100644 index 00000000..db8fb7e1 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/IPhaseSectionRepository.cs @@ -0,0 +1,6 @@ +using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain._Common; +namespace GozareshgirProgramManager.Domain.ProjectAgg.Repositories; +public interface IPhaseSectionRepository : IRepository +{ +} diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/IProjectPhaseRepository.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/IProjectPhaseRepository.cs new file mode 100644 index 00000000..8a29e014 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/IProjectPhaseRepository.cs @@ -0,0 +1,33 @@ +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities; + +namespace GozareshgirProgramManager.Domain.ProjectAgg.Repositories; + +/// +/// Repository interface for ProjectPhase entity +/// +public interface IProjectPhaseRepository : IRepository +{ + /// + /// Get phase with all its tasks + /// + Task GetWithTasksAsync(Guid phaseId); + + /// + /// Get phases by project ID + /// + Task> GetByProjectIdAsync(Guid projectId); + + + /// + /// Get phases with assignment overrides + /// + Task> GetPhasesWithAssignmentOverridesAsync(); + + /// + /// Get phases by status + /// + Task> GetByStatusAsync(ProjectAgg.Enums.PhaseStatus status); + + void Remove(ProjectPhase phase); +} diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/IProjectRepository.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/IProjectRepository.cs new file mode 100644 index 00000000..5514e492 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/IProjectRepository.cs @@ -0,0 +1,38 @@ +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities; + +namespace GozareshgirProgramManager.Domain.ProjectAgg.Repositories; + +/// +/// Repository interface for Project aggregate root +/// +public interface IProjectRepository : IRepository +{ + /// + /// Get project with all its phases and tasks + /// + Task GetWithFullHierarchyAsync(Guid projectId); + + /// + /// Get project with phases only + /// + Task GetWithPhasesAsync(Guid projectId); + + /// + /// Get projects by status + /// + Task> GetByStatusAsync(ProjectAgg.Enums.ProjectStatus status); + + + /// + /// Get projects with assignment overrides + /// + Task> GetProjectsWithAssignmentOverridesAsync(); + + /// + /// Search projects by name + /// + Task> SearchByNameAsync(string searchTerm); + + void Remove(Project project); +} diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/IProjectSectionRepository.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/IProjectSectionRepository.cs new file mode 100644 index 00000000..2838c8d6 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/IProjectSectionRepository.cs @@ -0,0 +1,9 @@ +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities; + +namespace GozareshgirProgramManager.Domain.ProjectAgg.Repositories; + +public interface IProjectSectionRepository : IRepository +{ +} + diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/IProjectTaskRepository.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/IProjectTaskRepository.cs new file mode 100644 index 00000000..8b0ff688 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/IProjectTaskRepository.cs @@ -0,0 +1,47 @@ +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities; + +namespace GozareshgirProgramManager.Domain.ProjectAgg.Repositories; + +/// +/// Repository interface for ProjectTask entity +/// +public interface IProjectTaskRepository : IRepository +{ + /// + /// Get task with all its sections + /// + Task GetWithSectionsAsync(Guid taskId); + + /// + /// Get tasks by phase ID + /// + Task> GetByPhaseIdAsync(Guid phaseId); + + /// + /// Get tasks with time overrides + /// + Task> GetTasksWithTimeOverridesAsync(); + + /// + /// Get tasks with assignment overrides + /// + Task> GetTasksWithAssignmentOverridesAsync(); + + /// + /// Get tasks by status + /// + Task> GetByStatusAsync(ProjectAgg.Enums.TaskStatus status); + + /// + /// Get tasks by priority + /// + Task> GetByPriorityAsync(ProjectAgg.Enums.TaskPriority priority); + + /// + /// Get tasks assigned to user + /// + Task> GetAssignedToUserAsync(long userId); + + void Remove(ProjectTask task); +} diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/ITaskSectionActivityRepository.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/ITaskSectionActivityRepository.cs new file mode 100644 index 00000000..d20ef6e0 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/ITaskSectionActivityRepository.cs @@ -0,0 +1,16 @@ +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities; + +namespace GozareshgirProgramManager.Domain.ProjectAgg.Repositories; + +public interface ITaskSectionActivityRepository:IRepository +{ + Task GetByIdAsync(Guid id); + Task> GetBySectionIdAsync(Guid sectionId); + Task> GetByUserIdAsync(long userId); + Task> GetActiveByUserAsync(long userId); + Task> GetByDateRangeAsync(DateTime from, DateTime to); + Task> GetByDateRangeUserIdAsync(DateTime from, DateTime to,long userId); + Task GetTotalTimeSpentByUserInRangeAsync(long userId, DateTime from, DateTime to); + Task> GetTotalTimeSpentPerUserInRangeAsync(DateTime from, DateTime to); +} \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/ITaskSectionRepository.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/ITaskSectionRepository.cs new file mode 100644 index 00000000..bedf59bf --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Repositories/ITaskSectionRepository.cs @@ -0,0 +1,12 @@ +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities; + +namespace GozareshgirProgramManager.Domain.ProjectAgg.Repositories; + +public interface ITaskSectionRepository: IRepository +{ + Task GetByIdWithActivitiesAsync(Guid id, CancellationToken cancellationToken = default); + + + Task GetByIdWithFullDataAsync(Guid id, CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/ValueObjects/TimeTracking.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/ValueObjects/TimeTracking.cs new file mode 100644 index 00000000..1018b220 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/ValueObjects/TimeTracking.cs @@ -0,0 +1,75 @@ +using GozareshgirProgramManager.Domain._Common; + +namespace GozareshgirProgramManager.Domain.ProjectAgg.ValueObjects; + +public class TimeRange : ValueObject +{ + public DateTime Start { get; private set; } + public DateTime? End { get; private set; } + + public TimeRange(DateTime start) + { + Start = start; + } + + public TimeRange(DateTime start, DateTime end) + { + if (start >= end) + throw new ArgumentException("Start time must be before end time"); + + Start = start; + End = end; + } + + public TimeSpan Duration => End.HasValue ? End.Value - Start : DateTime.UtcNow - Start; + public bool IsActive => !End.HasValue; + + public void Complete(DateTime endTime) + { + if (End.HasValue) + throw new InvalidOperationException("Time range is already completed"); + + if (endTime <= Start) + throw new ArgumentException("End time must be after start time"); + + End = endTime; + } + + protected override IEnumerable GetEqualityComponents() + { + yield return Start; + yield return End ?? DateTime.MinValue; + } +} + +public class WorkSession : ValueObject +{ + public long UserId { get; private set; } + public TimeRange TimeRange { get; private set; } + public string? Notes { get; private set; } + public string? EndNotes { get; private set; } + + public WorkSession(long userId, DateTime startTime, string? notes = null) + { + UserId = userId; + TimeRange = new TimeRange(startTime); + Notes = notes; + } + + public void Complete(DateTime endTime, string? endNotes = null) + { + TimeRange.Complete(endTime); + EndNotes = endNotes; + } + + public TimeSpan Duration => TimeRange.Duration; + public bool IsActive => TimeRange.IsActive; + + protected override IEnumerable GetEqualityComponents() + { + yield return UserId; + yield return TimeRange; + yield return Notes ?? string.Empty; + yield return EndNotes ?? string.Empty; + } +} diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/ValueObjects/UserSkillAssignment.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/ValueObjects/UserSkillAssignment.cs new file mode 100644 index 00000000..491e2000 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/ValueObjects/UserSkillAssignment.cs @@ -0,0 +1,31 @@ +namespace GozareshgirProgramManager.Domain.ProjectAgg.ValueObjects; + +/// +/// Value Object برای ذخیره تخصیص کاربر و مهارت در سطوح بالاتر (Project/Phase) +/// این اطلاعات می‌تواند به صورت shortcut در Task و Section استفاده شود +/// +public class UserSkillAssignment +{ + public UserSkillAssignment(long userId, Guid skillId) + { + UserId = userId; + SkillId = skillId; + } + + public long UserId { get; private set; } + public Guid SkillId { get; private set; } + + public override bool Equals(object? obj) + { + if (obj is not UserSkillAssignment other) + return false; + + return UserId == other.UserId && SkillId == other.SkillId; + } + + public override int GetHashCode() + { + return HashCode.Combine(UserId, SkillId); + } +} + diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/RoleAgg/Entities/Role.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/RoleAgg/Entities/Role.cs new file mode 100644 index 00000000..81bb10ba --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/RoleAgg/Entities/Role.cs @@ -0,0 +1,48 @@ +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.PermissionAgg.Entities; +using System.Security.Principal; +using System.Xml.Linq; +using GozareshgirProgramManager.Domain.UserAgg.Entities; + +namespace GozareshgirProgramManager.Domain.RoleAgg.Entities; + +public class Role : EntityBase +{ + /// + /// نام نقش + /// + public string RoleName { get; private set; } + + + /// + /// لیست پرمیشن کد ها + /// + public List Permissions { get; private set; } + + /// + /// ای دی نقش در گزارشگیر + /// + public long? GozareshgirRoleId { get; private set; } + + + protected Role() + { + } + + public Role(string roleName,long? gozareshgirRolId, List permissions) + { + RoleName = roleName; + Permissions = permissions; + GozareshgirRoleId = gozareshgirRolId; + + } + + + public void Edit(string roleName, List permissions) + { + RoleName = roleName; + Permissions = permissions; + } + + +} \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/RoleAgg/Repositories/IRoleRepository.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/RoleAgg/Repositories/IRoleRepository.cs new file mode 100644 index 00000000..6d30ae22 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/RoleAgg/Repositories/IRoleRepository.cs @@ -0,0 +1,12 @@ +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.RoleAgg.Entities; +using GozareshgirProgramManager.Domain.UserAgg.Entities; + +namespace GozareshgirProgramManager.Domain.RoleAgg.Repositories; + +public interface IRoleRepository : IRepository +{ + Task GetByGozareshgirRoleIdAsync(long? gozareshgirRolId); + + +} \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/RoleUserAgg/RoleUser.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/RoleUserAgg/RoleUser.cs new file mode 100644 index 00000000..b8a05dc9 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/RoleUserAgg/RoleUser.cs @@ -0,0 +1,19 @@ +using GozareshgirProgramManager.Domain.UserAgg.Entities; + +namespace GozareshgirProgramManager.Domain.RoleUserAgg; + +public class RoleUser +{ + public RoleUser(long roleId) + { + RoleId = roleId; + } + + public long Id { get; private set; } + public long RoleId { get; private set; } + + + public User User { get; set; } + + +} \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/SalaryPaymentSettingAgg/DTOs/UserSalarySettingDto.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/SalaryPaymentSettingAgg/DTOs/UserSalarySettingDto.cs new file mode 100644 index 00000000..12e5f50d --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/SalaryPaymentSettingAgg/DTOs/UserSalarySettingDto.cs @@ -0,0 +1,43 @@ +using GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Enums; + +namespace GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.DTOs; + +public record UserSalarySettingDto +{ + + /// + /// آی دی کاربر + /// + public long UserId { get; set; } + + /// + /// کار در تعطیلات رسمی + /// + public bool HolidayWorking { get; set; } + + /// + /// حقوق ماهانه + /// + public double MonthlySalary { get; set; } + + + public string FullName { get; set; } + + public List WorkingHoursListDto { get; set; } +} + + +public record WorkingHoursListDto +{ + /// + /// مدت زمان شیفت + /// + public TimeSpan ShiftDuration { get; set; } + /// + /// عدد روز از ماه + /// + public PersianDayOfWeek PersianDayOfWeek { get; set; } + + + +} \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/SalaryPaymentSettingAgg/Entities/SalaryPaymentSetting.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/SalaryPaymentSettingAgg/Entities/SalaryPaymentSetting.cs new file mode 100644 index 00000000..d98e3454 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/SalaryPaymentSettingAgg/Entities/SalaryPaymentSetting.cs @@ -0,0 +1,94 @@ +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.UserAgg.Entities; + +namespace GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities; + +/// +/// تنظیمات پرداخت حقوق +/// +public class SalaryPaymentSetting : EntityBase +{ + /// + /// ایجاد تنظیمات حقوق + /// برای اولین بار + /// + /// + /// + /// + /// + public SalaryPaymentSetting(bool holidayWorking, long userId, double monthlySalary, List workingHoursList) + { + HolidayWorking = holidayWorking; + UserId = userId; + MonthlySalary = monthlySalary; + WorkingHoursList = workingHoursList; + StartSettingDate = new DateTime(2025, 3, 21); + } + /// + /// افزودن تنظیمات جدید + /// + /// + /// + /// + /// + /// + public SalaryPaymentSetting(bool holidayWorking, long userId, List workingHoursList, DateTime startSettingDate) + { + HolidayWorking = holidayWorking; + UserId = userId; + + WorkingHoursList = workingHoursList; + StartSettingDate = startSettingDate; + } + + + protected SalaryPaymentSetting() + { + + } + + /// + /// کارکردن در تعطیلات رسمی + /// + public bool HolidayWorking { get; private set; } + + + /// + /// آی دی کاربر + /// + public long UserId { get; private set; } + + /// + /// دستمزد ماهانه + /// + public double MonthlySalary { get; private set; } + + /// + /// تاریخ شروع تنظیمات + /// + public DateTime? StartSettingDate { get; private set; } + + /// + /// تاریخ پایان تنظیمات + /// + public DateTime? EndSettingDate { get; private set; } + + + public List WorkingHoursList { get; set; } + + + /// + /// ویرایش تنظیمات حقوق + /// + /// + /// + public void Edit(bool holidayWorking, double monthlySalary, List workingHoursList) + { + HolidayWorking = holidayWorking; + WorkingHoursList = workingHoursList; + MonthlySalary = monthlySalary; + } + + + +} \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/SalaryPaymentSettingAgg/Entities/WorkingHours.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/SalaryPaymentSettingAgg/Entities/WorkingHours.cs new file mode 100644 index 00000000..0522364f --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/SalaryPaymentSettingAgg/Entities/WorkingHours.cs @@ -0,0 +1,164 @@ +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Enums; +using System.ComponentModel.DataAnnotations.Schema; + +namespace GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities; + +/// +/// تخصیص ساعت کاری به کاربر +/// +public class WorkingHours +{ + public WorkingHours(TimeSpan startShiftOne, TimeSpan endShiftOne, TimeSpan startShiftTwo, TimeSpan endShiftTwo, TimeSpan restTime, bool hasShiftOne, bool hasShiftTwo, bool hasRestTime, PersianDayOfWeek persianDayOfWeek, bool isActiveDay) + { + StartShiftOne = hasShiftOne? startShiftOne : TimeSpan.Zero; + EndShiftOne = hasShiftOne ? endShiftOne : TimeSpan.Zero; + StartShiftTwo = hasShiftTwo ? startShiftTwo : TimeSpan.Zero; + EndShiftTwo = hasShiftTwo ? endShiftTwo : TimeSpan.Zero; + RestTime = hasRestTime ? restTime : TimeSpan.Zero; + HasShiftOne = hasShiftOne; + HasShiftTow = hasShiftTwo; + HasRestTime = hasRestTime; + PersianDayOfWeek = persianDayOfWeek; + IsActiveDay = isActiveDay; + + ComputeShiftDuration(startShiftOne, endShiftOne, startShiftTwo, endShiftTwo, restTime, hasShiftOne, hasShiftTwo,hasRestTime); + } + + + private WorkingHours(bool isActiveDay) + { + IsActiveDay = isActiveDay; + } + + public long Id { get; private set; } + + /// + /// ساعت شروع شیفت کاری + /// + public TimeSpan StartShiftOne { get; private set; } + + /// + /// ساعت پایان شیفت کاری + /// + public TimeSpan EndShiftOne { get; private set; } + + + /// + /// ساعت شروع شیفت دوم کاری + /// + public TimeSpan StartShiftTwo { get; private set; } + + /// + /// ساعت پایان شیفت دوم کاری + /// + public TimeSpan EndShiftTwo { get; private set; } + + /// + /// مدت استراحت + /// + public TimeSpan RestTime { get; private set; } + + + /// + /// آیا مقطع مار اول دارد + /// + public bool HasShiftOne { get; private set; } + + /// + /// آیا مقطع کار دوم دارد + /// + public bool HasShiftTow { get; private set; } + + /// + /// آیا ساعت استراحت دارد + /// + public bool HasRestTime { get; private set; } + + /// + /// بازه زمانی شیفت + /// + public int ShiftDurationInMinutes { get; private set; } + + [NotMapped] + public TimeSpan ShiftDuration + { + get => TimeSpan.FromMinutes(ShiftDurationInMinutes); + private set => ShiftDurationInMinutes = (int)value.TotalMinutes; + } + + /// + /// عدد روز از ماه + /// + public PersianDayOfWeek PersianDayOfWeek { get; private set; } + + + + + /// + /// آیا این روز هفته + /// فعال است + /// + public bool IsActiveDay { get; private set; } + + public SalaryPaymentSetting SalaryPaymentSetting { get; set; } + + /// + /// بدست آوردن بازه زمانی شیفت + /// + /// + /// + /// + private void ComputeShiftDuration(TimeSpan startShift, TimeSpan endShift, TimeSpan startShiftTwo, TimeSpan endShiftTwo, TimeSpan restTime, bool hasShiftOne, bool hasShiftTwo, bool hasRestTime) + { + var now = DateTime.Now.Date; + + if (hasShiftOne && !hasShiftTwo) + { + DateTime startOne = new DateTime(now.Year, now.Month, now.Day, startShift.Hours, startShift.Minutes,0); + DateTime endOne = new DateTime(now.Year, now.Month, now.Day, endShift.Hours, endShift.Minutes, 0); + + + if (endOne <= startOne) + endOne = endOne.AddDays(1); + var shiftDuration = (endOne - startOne); + + ShiftDuration = hasRestTime ? (shiftDuration - restTime) : shiftDuration; + } + else if (!hasShiftOne && hasShiftTwo) + { + DateTime startTow = new DateTime(now.Year, now.Month, now.Day, startShiftTwo.Hours, startShiftTwo.Minutes, 0); + DateTime endTow = new DateTime(now.Year, now.Month, now.Day, endShiftTwo.Hours, endShiftTwo.Minutes, 0); + + if (endTow <= startTow) + endTow = endTow.AddDays(1); + + + ShiftDuration = (endTow - startTow); + } + else if (hasShiftOne && hasShiftTwo) + { + DateTime startOne = new DateTime(now.Year, now.Month, now.Day, startShift.Hours, startShift.Minutes, 0); + DateTime endOne = new DateTime(now.Year, now.Month, now.Day, endShift.Hours, endShift.Minutes, 0); + if (endOne <= startOne){} + endOne = endOne.AddDays(1); + + var shiftOneDuration = (endOne - startOne); + + DateTime startTow = new DateTime(endOne.Year, endOne.Month, endOne.Day, startShiftTwo.Hours, startShiftTwo.Minutes, 0); + DateTime endTow = new DateTime(endOne.Year, endOne.Month, endOne.Day, endShiftTwo.Hours, endShiftTwo.Minutes, 0); + + if (endTow <= startTow) + endTow = endTow.AddDays(1); + + var shiftDurationTow = (endTow - startTow); + ShiftDuration = shiftOneDuration.Add(shiftDurationTow); + } + else + { + ShiftDurationInMinutes = 0; + } + + } + +} \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/SalaryPaymentSettingAgg/Enums/HasSalarySettings.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/SalaryPaymentSettingAgg/Enums/HasSalarySettings.cs new file mode 100644 index 00000000..589c71d1 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/SalaryPaymentSettingAgg/Enums/HasSalarySettings.cs @@ -0,0 +1,20 @@ +namespace GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Enums; + +public enum HasSalarySettings +{ + /// + /// پیش فرض هر دو حالت + /// + Default = 0, + + /// + /// تنظیمات حقوق و ساعت دارد + /// + HasSettings = 1, + /// + /// تنظیمات حقوق و ساعت ندارد + /// + DoesNotHaveSettings = 2 + + +} \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/SalaryPaymentSettingAgg/Enums/PersianDayOfWeek.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/SalaryPaymentSettingAgg/Enums/PersianDayOfWeek.cs new file mode 100644 index 00000000..ad78b55a --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/SalaryPaymentSettingAgg/Enums/PersianDayOfWeek.cs @@ -0,0 +1,29 @@ +namespace GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Enums; + +public enum PersianDayOfWeek +{ + /// شنبه + Shanbeh = 1, + + /// یکشنبه + YekShanbeh = 2, + + /// دوشنبه + DoShanbeh = 3, + + /// سه شنبه + SeShanbeh = 4, + + /// چهارشنبه + CheharShanbeh = 5, + + /// پنجشنبه + PanjShanbeh = 6, + + /// جمعه + Jomeh = 7, + + + + +} \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/SalaryPaymentSettingAgg/Repositories/ISalaryPaymentSettingRepository.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/SalaryPaymentSettingAgg/Repositories/ISalaryPaymentSettingRepository.cs new file mode 100644 index 00000000..4bc45f73 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/SalaryPaymentSettingAgg/Repositories/ISalaryPaymentSettingRepository.cs @@ -0,0 +1,26 @@ +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.DTOs; +using GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities; + +namespace GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Repositories; + +public interface ISalaryPaymentSettingRepository : IRepository +{ + /// + /// دریافت لیست تنظیمات حقوق + /// + /// + /// + Task GetSalarySettingByUserId(long userId); + + + Task> GetAllSettings(List userIdList); + + /// + /// حذف گروهی تنظیمات حقوق + /// + /// + /// + void RemoveRangeSalarySettings(List removedItems); +} + diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/SkillAgg/Entities/Skill.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/SkillAgg/Entities/Skill.cs new file mode 100644 index 00000000..662f9544 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/SkillAgg/Entities/Skill.cs @@ -0,0 +1,16 @@ +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities; + +namespace GozareshgirProgramManager.Domain.SkillAgg.Entities; + +public class Skill:EntityBase, IAggregateRoot +{ + public Skill(string name) + { + Name = name; + Sections = []; + } + + public string Name { get; set; } + public List Sections { get; set; } +} \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/SkillAgg/Repositories/ISkillRepository.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/SkillAgg/Repositories/ISkillRepository.cs new file mode 100644 index 00000000..e6152c60 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/SkillAgg/Repositories/ISkillRepository.cs @@ -0,0 +1,9 @@ +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.SkillAgg.Entities; + +namespace GozareshgirProgramManager.Domain.SkillAgg.Repositories; + +public interface ISkillRepository: IRepository +{ + +} \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/UserAgg/Entities/User.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/UserAgg/Entities/User.cs new file mode 100644 index 00000000..d112136d --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/UserAgg/Entities/User.cs @@ -0,0 +1,169 @@ +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.PermissionAgg.Entities; +using GozareshgirProgramManager.Domain.RoleAgg.Entities; +using GozareshgirProgramManager.Domain.RoleUserAgg; + +namespace GozareshgirProgramManager.Domain.UserAgg.Entities; + +/// +/// کاربر +/// +public class User : EntityBase +{ + /// + /// ایجاد + /// + /// + /// + /// + /// + /// + /// + /// + public User(string fullName, string userName, string password, string mobile, string? email, long? accountId, List roles) + { + FullName = fullName; + UserName = userName; + Password = password; + Mobile = mobile; + Email = email; + IsActive = true; + AccountId = accountId; + RoleUser = roles; + } + + protected User() + { + + } + /// + /// نام و نام خانوادگی + /// + public string FullName { get; private set; } + + /// + /// نام کاربری + /// + public string UserName { get; private set; } + + /// + /// گذرواژه + /// + public string Password { get; private set; } + + /// + /// مسیر عکس پروفایل + /// + public string ProfilePhotoPath { get; private set; } + + /// + /// شماره موبایل + /// + public string Mobile { get; set; } + + /// + /// ایمیل + /// + public string? Email { get; private set; } + + /// + /// فعال/غیر فعال بودن یوزر + /// + public bool IsActive { get; private set; } + + + /// + /// کد یکبارمصرف ورود + /// + public string? VerifyCode { get; private set; } + + /// + /// آی دی کاربر در گزارشگیر + /// + public long? AccountId { get; private set; } + + + /// + /// لیست پرمیشن کد ها + /// + public List RoleUser { get; private set; } + + /// + /// لیست توکن‌های تازه‌سازی + /// + private List _refreshTokens = new(); + public IReadOnlyCollection RefreshTokens => _refreshTokens.AsReadOnly(); + + /// + /// آپدیت کاربر + /// + /// + /// + /// + /// + /// + public void Edit(string fullName, string userName, string mobile, List roles, bool isActive) + { + FullName = fullName; + UserName = userName; + Mobile = mobile; + RoleUser = roles; + IsActive = isActive; + } + + /// + /// غیرفعال سازی + /// + public void DeActive() + { + IsActive = false; + } + + /// + /// فعال سازی + /// + public void ReActive() + { + IsActive = true; + } + + /// + /// افزودن توکن تازه‌سازی + /// + public void AddRefreshToken(string token, DateTime expiresAt, string? ipAddress = null, string? userAgent = null) + { + var refreshToken = new UserRefreshToken(Id, token, expiresAt, ipAddress, userAgent); + _refreshTokens.Add(refreshToken); + } + + /// + /// لغو توکن تازه‌سازی + /// + public void RevokeRefreshToken(string token) + { + var refreshToken = _refreshTokens.FirstOrDefault(x => x.Token == token); + if (refreshToken == null) + throw new InvalidOperationException("توکن یافت نشد"); + + refreshToken.Revoke(); + } + + /// + /// لغو تمام توکن‌های فعال + /// + public void RevokeAllRefreshTokens() + { + foreach (var token in _refreshTokens.Where(x => x.IsActive)) + { + token.Revoke(); + } + } + + /// + /// پاکسازی توکن‌های منقضی شده + /// + public void RemoveExpiredRefreshTokens() + { + _refreshTokens.RemoveAll(x => !x.IsActive); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/UserAgg/Entities/UserRefreshToken.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/UserAgg/Entities/UserRefreshToken.cs new file mode 100644 index 00000000..b04b3615 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/UserAgg/Entities/UserRefreshToken.cs @@ -0,0 +1,90 @@ +using GozareshgirProgramManager.Domain._Common; + +namespace GozareshgirProgramManager.Domain.UserAgg.Entities; + +/// +/// توکن تازه‌سازی برای احراز هویت +/// +public class UserRefreshToken : EntityBase +{ + /// + /// سازنده محافظت شده برای EF Core + /// + protected UserRefreshToken() + { + } + + /// + /// ایجاد توکن تازه‌سازی + /// + public UserRefreshToken(long userId, string token, DateTime expiresAt, string? ipAddress = null, string? userAgent = null) + { + UserId = userId; + Token = token; + ExpiresAt = expiresAt; + IpAddress = ipAddress; + UserAgent = userAgent; + } + + /// + /// شناسه کاربر + /// + public long UserId { get; private set; } + + /// + /// توکن تازه‌سازی + /// + public string Token { get; private set; } + + /// + /// تاریخ انقضا + /// + public DateTime ExpiresAt { get; private set; } + + /// + /// تاریخ لغو + /// + public DateTime? RevokedAt { get; private set; } + + /// + /// آی‌پی کاربر + /// + public string? IpAddress { get; private set; } + + /// + /// User Agent مرورگر + /// + public string? UserAgent { get; private set; } + + /// + /// آیا منقضی شده؟ + /// + public bool IsExpired => DateTime.Now >= ExpiresAt; + + /// + /// آیا لغو شده؟ + /// + public bool IsRevoked => RevokedAt.HasValue; + + /// + /// آیا فعال است؟ + /// + public bool IsActive => !IsRevoked && !IsExpired; + + /// + /// لغو توکن + /// + public void Revoke() + { + if (IsRevoked) + throw new InvalidOperationException("توکن قبلاً لغو شده است"); + + RevokedAt = DateTime.Now; + } + + /// + /// کاربر صاحب توکن + /// + public User User { get; private set; } +} + diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/UserAgg/Enums/ExternalAuthProvider.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/UserAgg/Enums/ExternalAuthProvider.cs new file mode 100644 index 00000000..e02abfc9 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/UserAgg/Enums/ExternalAuthProvider.cs @@ -0,0 +1 @@ + diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/UserAgg/Events/UserEvents.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/UserAgg/Events/UserEvents.cs new file mode 100644 index 00000000..83b95f05 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/UserAgg/Events/UserEvents.cs @@ -0,0 +1,47 @@ +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.UserAgg.Entities; + + +namespace GozareshgirProgramManager.Domain.UserAgg.Events; + +public record UserCreatedEvent(long UserId, string FirstName, string LastName, string Email) : IDomainEvent +{ + public DateTime OccurredOn { get; init; } = DateTime.UtcNow; +} + +public record UserPersonalInfoUpdatedEvent(long UserId, string OldFirstName, string OldLastName, string NewFirstName, string NewLastName) : IDomainEvent +{ + public DateTime OccurredOn { get; init; } = DateTime.UtcNow; +} + +public record UserEmailUpdatedEvent(long UserId, string OldEmail, string NewEmail) : IDomainEvent +{ + public DateTime OccurredOn { get; init; } = DateTime.UtcNow; +} + +public record UserWorkInfoUpdatedEvent(long UserId, string? Department, string? Position) : IDomainEvent +{ + public DateTime OccurredOn { get; init; } = DateTime.UtcNow; +} + + + + + + + + +public record UserDeactivatedEvent(long UserId, string? Reason) : IDomainEvent +{ + public DateTime OccurredOn { get; init; } = DateTime.UtcNow; +} + +public record UserActivatedEvent(long UserId) : IDomainEvent +{ + public DateTime OccurredOn { get; init; } = DateTime.UtcNow; +} + +public record UserLoggedInEvent(long UserId, DateTime LoginTime) : IDomainEvent +{ + public DateTime OccurredOn { get; init; } = DateTime.UtcNow; +} diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/UserAgg/Repositories/IUserRefreshTokenRepository.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/UserAgg/Repositories/IUserRefreshTokenRepository.cs new file mode 100644 index 00000000..62146e68 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/UserAgg/Repositories/IUserRefreshTokenRepository.cs @@ -0,0 +1,9 @@ +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.UserAgg.Entities; + +namespace GozareshgirProgramManager.Domain.UserAgg.Repositories; + +public interface IUserRefreshTokenRepository : IRepository +{ + +} \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/UserAgg/Repositories/IUserRepository.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/UserAgg/Repositories/IUserRepository.cs new file mode 100644 index 00000000..5ce68190 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/UserAgg/Repositories/IUserRepository.cs @@ -0,0 +1,32 @@ +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.UserAgg.Entities; + +namespace GozareshgirProgramManager.Domain.UserAgg.Repositories; + +public interface IUserRepository: IRepository +{ + Task GetByIdAsync(long id); + + /// + /// یافتن کاربر با آی دی اکانت گزارشگیر او + /// + /// + /// + Task GetByGozareshgirAccountId(long accountId); + Task GetByEmailAsync(string email); + Task GetByMobileAsync(string mobile); + Task> GetAllAsync(); + Task> GetActiveUsersAsync(); + + Task AddAsync(User user); + void Update(User user); + void Delete(User user); + Task ExistsAsync(long id); + Task UsernameExistsAsync(string username); + Task EmailExistsAsync(string email); + Task MobileExistsAsync(string mobile); + Task GetUserWithRolesByIdAsync(long userId, CancellationToken cancellationToken); +} + + + diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/EntityBase.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/EntityBase.cs new file mode 100644 index 00000000..1710c77b --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/EntityBase.cs @@ -0,0 +1,25 @@ +using System.ComponentModel.DataAnnotations.Schema; + +namespace GozareshgirProgramManager.Domain._Common; + +public abstract class EntityBase +{ + public EntityBase() + { + if (typeof(TId) == typeof(Guid)) + { + Id = (TId)(object)Guid.NewGuid(); + } + CreationDate = DateTime.Now; + } + public TId Id { get; protected set; } + public DateTime CreationDate { get; protected set; } + + private readonly List _domainEvents = new(); + [NotMapped] + public IReadOnlyCollection DomainEvents => _domainEvents.AsReadOnly(); + protected void AddDomainEvent(IDomainEvent domainEvent) => _domainEvents.Add(domainEvent); + public void ClearDomainEvents() => _domainEvents.Clear(); + + +} \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/Exceptions/BadRequestException.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/Exceptions/BadRequestException.cs new file mode 100644 index 00000000..c33adfa0 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/Exceptions/BadRequestException.cs @@ -0,0 +1,24 @@ +namespace GozareshgirProgramManager.Domain._Common.Exceptions; + +public class BadRequestException:Exception +{ + public BadRequestException(string message):base(message) + { + + } + + public BadRequestException(string message, string details) : base(message) + { + Details = details; + } + + public BadRequestException(string message, Dictionary extra) : + base(message) + { + Extra = extra; + } + + public string Details { get; } + public Dictionary Extra { get; set; } + +} \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/Exceptions/NotFoundException.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/Exceptions/NotFoundException.cs new file mode 100644 index 00000000..3b0f1796 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/Exceptions/NotFoundException.cs @@ -0,0 +1,13 @@ +namespace GozareshgirProgramManager.Domain._Common.Exceptions; + +public class NotFoundException:Exception +{ + public NotFoundException(string message) : base(message) + { + } + + public NotFoundException(string name, object key) : base($"Entity \"{name}\" ({key}) was not found.") + { + } + +} \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/Exceptions/UnAuthorizedException.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/Exceptions/UnAuthorizedException.cs new file mode 100644 index 00000000..67f0befb --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/Exceptions/UnAuthorizedException.cs @@ -0,0 +1,8 @@ +namespace GozareshgirProgramManager.Domain._Common.Exceptions; + +public class UnAuthorizedException:Exception +{ + public UnAuthorizedException(string message) : base(message) + { + } +} \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/IAggregateRoot.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/IAggregateRoot.cs new file mode 100644 index 00000000..b11ee26d --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/IAggregateRoot.cs @@ -0,0 +1,8 @@ +namespace GozareshgirProgramManager.Domain._Common; + +/// +/// Marker interface for Aggregate Roots +/// +public interface IAggregateRoot +{ +} diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/IDomainEvent.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/IDomainEvent.cs new file mode 100644 index 00000000..6ab51876 --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/IDomainEvent.cs @@ -0,0 +1,6 @@ +namespace GozareshgirProgramManager.Domain._Common; + +public interface IDomainEvent +{ + DateTime OccurredOn { get; } +} \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/IRepository.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/IRepository.cs new file mode 100644 index 00000000..cd8a9dcc --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/IRepository.cs @@ -0,0 +1,17 @@ +using System.Linq.Expressions; + +namespace GozareshgirProgramManager.Domain._Common; + +public interface IRepository where T:class +{ + T Get(TKey id); + Task GetByIdAsync(TKey id); + List Get(); + IQueryable GetQueryable(); + void Create(T entity); + Task CreateAsync(T entity); + bool ExistsIgnoreQueryFilter(Expression> expression); + bool Exists(Expression> expression); + //void SaveChanges(); + //Task SaveChangesAsync(); +} \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/IUnitOfWork.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/IUnitOfWork.cs new file mode 100644 index 00000000..1ecce3ef --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/IUnitOfWork.cs @@ -0,0 +1,9 @@ + namespace GozareshgirProgramManager.Domain._Common; + +/// +/// Unit of Work pattern interface +/// +public interface IUnitOfWork +{ + Task SaveChangesAsync(CancellationToken cancellationToken = default); +} diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/Tools.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/Tools.cs new file mode 100644 index 00000000..0f1ed2da --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/Tools.cs @@ -0,0 +1,2089 @@ +using System.Globalization; +using System.Text.RegularExpressions; +using PersianTools.Core; + + +namespace GozareshgirProgramManager.Domain._Common; + +public static class Tools +{ + + public static string[] MonthNames = + {"فروردین", "اردیبهشت", "خرداد", "تیر", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی", "بهمن", "اسفند"}; + + public static string[] DayNames = { "شنبه", "یکشنبه", "دو شنبه", "سه شنبه", "چهار شنبه", "پنج شنبه", "جمعه" }; + public static string[] DayNamesG = { "یکشنبه", "دو شنبه", "سه شنبه", "چهار شنبه", "پنج شنبه", "جمعه", "شنبه" }; + + + public static bool IsMobileValid(this string mobileNo) + { + if (mobileNo.Length < 11) + return false; + return Regex.IsMatch(mobileNo, "^((09))(\\d{9})$"); + } + + /// + /// تاریخ شروع و تعداد ماه را میگیرد و تاریخ پایان قراردا را بر میگرداند + /// + /// + /// + /// + public static (DateTime endDateGr, string endDateFa) FindEndOfContract(string startDate, string monthPlus) + { + + int startYear = Convert.ToInt32(startDate.Substring(0, 4)); + int startMonth = Convert.ToInt32(startDate.Substring(5, 2)); + int startDay = Convert.ToInt32(startDate.Substring(8, 2)); + var start = new PersianDateTime(startYear, startMonth, startDay); + var end = (start.AddMonths(Convert.ToInt32(monthPlus))).AddDays(-1); + return ($"{end}".ToGeorgianDateTime(), $"{end}"); + + } + + /// + /// دریافت روزهای کارکرد پرسنل در لیست بیمه ماه مشخص شده + /// با کمک شروع بکار و ترک کار + /// + /// + /// + /// + /// + /// + /// + public static (int countWorkingDays, DateTime startWork, DateTime endWork, bool hasStartWorkInMonth, bool hasLeftWorkInMonth) GetEmployeeInsuranceWorkingDays(DateTime startWork, DateTime? leftWork, DateTime startDate, + DateTime endDate, long employeeId) + { + DateTime start = startDate; + DateTime end = endDate; + bool startWorkInMonth = false; + bool endWorkInMonth = false; + + //اگر شروع بکار پرسنل در ماه مشخص شده لیست بیمه بود + if (startWork >= startDate) + { + start = startWork; + startWorkInMonth = true; + } + + if (leftWork == null) + leftWork = DateTime.MinValue; + //اگر ترک کار پرسنل در ماه مشخص شده لیست بیمه بود + if (leftWork != DateTime.MinValue && leftWork.Value < endDate) + { + end = leftWork.Value; + endWorkInMonth = true; + } + + int countDays = (int)(end - start).TotalDays + 1; + + + //روزهای کارکرد پرسنل با آی دی های زیر دستی تعریف شد + switch (employeeId) + { + + //case 3812://ثابت- کسری حاجی پور + // countWorkingDays = 15; + // break; + case 40463://ثابت + countDays = 10; + break; + case 40469://ثابت + countDays = 7; + break; + //case 9950://ثابت + // countDays = 15; + //break; + case 9640://ثابت + countDays = 15; + break; + case 40998://ثابت + countDays = 15; + break; + case 6219://ثابت + countDays = 15; + break; + //case 7897://ثابت + // countWorkingDays = 15; + } + + + return (countDays, start, end, startWorkInMonth, endWorkInMonth); + } + /// + /// محاسبه سن + /// + /// + /// + /// + public static (int yearCount, int monthCount, int dayCount) GetAge(DateTime startDate, DateTime endDate) + { + + var startFa = startDate.ToFarsi(); + int startYear = Convert.ToInt32(startFa.Substring(0, 4)); + int startMonth = Convert.ToInt32(startFa.Substring(5, 2)); + int startDay = Convert.ToInt32(startFa.Substring(8, 2)); + var start = new PersianDateTime(startYear, startMonth, startDay); + + + var endFa = endDate.ToFarsi(); + int endYear = Convert.ToInt32(endFa.Substring(0, 4)); + int endMonth = Convert.ToInt32(endFa.Substring(5, 2)); + int endDay = Convert.ToInt32(endFa.Substring(8, 2)); + var end = new PersianDateTime(endYear, endMonth, endDay); + int months = 0; + int days = 0; + int years = 0; + + var firstYearCounter = start.AddYears(1); + //اگر سنش هنوز به یک سال نرسیده بود + if (firstYearCounter > end) + { + start = start.AddYears(-1); + + var endMonthCounter = new PersianDateTime(end.Year, end.Month, start.Day); + + for (var monthCounter = start; monthCounter <= end; monthCounter = monthCounter.AddMonths(1)) + { + if (monthCounter <= end) + { + Console.ForegroundColor = ConsoleColor.Yellow; + Console.WriteLine("month : " + monthCounter); + months++; + } + + if (monthCounter.Month == end.Month) + { + var firstDayCounter = monthCounter.AddDays(1); + for (var dayCounter = firstDayCounter; dayCounter <= end; dayCounter = dayCounter.AddDays(1)) + { + if (dayCounter <= end) + { + days++; + Console.ForegroundColor = ConsoleColor.Cyan; + Console.WriteLine("day : " + dayCounter); + + } + + } + months = months > 0 ? months - 1 : 0; + break; + } + + + + } + + + } + else + { + for (var yearCouner = firstYearCounter; yearCouner <= end; yearCouner = yearCouner.AddYears(1)) + { + + if (yearCouner.Year <= end.Year) + { + years++; + Console.ForegroundColor = ConsoleColor.DarkMagenta; + Console.WriteLine("year : " + yearCouner); + } + + + if (yearCouner.Year == end.Year) + { + + var endMonthCounter = new PersianDateTime(end.Year, end.Month, (yearCouner.Day > end.Day ? end.Day : yearCouner.Day)); + + if (yearCouner.Day <= end.Day) + { + endMonthCounter = end; + + } + for (var monthCounter = yearCouner; monthCounter <= endMonthCounter; monthCounter = monthCounter.AddMonths(1)) + { + if (monthCounter < end) + { + Console.ForegroundColor = ConsoleColor.Yellow; + Console.WriteLine("month : " + monthCounter); + months++; + } + + if (monthCounter.Month == end.Month) + { + var firstDayCounter = monthCounter.AddDays(1); + if (yearCouner.Day > end.Day) + { + + firstDayCounter = firstDayCounter.AddMonths(-1); + } + for (var dayCounter = firstDayCounter; dayCounter <= end; dayCounter = dayCounter.AddDays(1)) + { + if (dayCounter <= end) + { + days++; + Console.ForegroundColor = ConsoleColor.Cyan; + Console.WriteLine("day : " + dayCounter); + + } + + } + + months = months > 0 ? months - 1 : 0; + break; + } + + + } + + } + + } + } + + + Console.ResetColor(); + Console.WriteLine($"old: [{years} year] ، [{months} month] ، [{days} day]"); + return (years, months, days); + } + + public static string ToFarsi(this DateTime? date) + { + try + { + if (date != null) return date.Value.ToFarsi(); + } + catch (Exception) + { + return ""; + } + + return ""; + } + + public static string ToFarsi(this DateTime date) + { + if (date == new DateTime()) return ""; + var pc = new PersianCalendar(); + return $"{pc.GetYear(date)}/{pc.GetMonth(date):00}/{pc.GetDayOfMonth(date):00}"; + } + public static string ToFarsiMonth(this DateTime date) + { + if (date == new DateTime()) return ""; + var pc = new PersianCalendar(); + return $"{pc.GetMonth(date)}"; + } + + /// + /// دریافت عدد ماه شمسی + /// از تاریخ میلادی + /// + /// + /// + public static string GetShamsiMonthNumber(this DateTime date) + { + if (date == new DateTime()) return ""; + var pc = new PersianCalendar(); + return $"{pc.GetMonth(date):00}"; + } + /// + /// دریافت ساتل شمسی + /// از تاریخ میلادی + /// + /// + /// + public static string GetShamsiYearNumber(this DateTime date) + { + if (date == new DateTime()) return ""; + var pc = new PersianCalendar(); + return $"{pc.GetYear(date)}"; + } + /// + /// این متد تاریخ میلادی را گرفته و ماه 31 یا 30 روزه را تشخیص میدهد، ماه اسفند 30 روزه برمگیردد + /// + /// + /// + public static int CountMonthDays(this DateTime date) + { + if (date == new DateTime()) return 0; + var pc = new PersianCalendar(); + + return pc.GetMonth(date) switch + { + 1 => 31, + 2 => 31, + 3 => 31, + 4 => 31, + 5 => 31, + 6 => 31, + + 7 => 30, + 8 => 30, + 9 => 30, + 10 => 30, + 11 => 30, + 12 => 30, + _ => 0, + + }; + } + + public static string ToFarsiYear2(this DateTime date) + { + if (date == new DateTime()) return ""; + var pc = new PersianCalendar(); + var year = pc.GetYear(date).ToString(); + string y1 = string.Empty; + string y2 = string.Empty; + string sum = string.Empty; + for (int i = 0; i < year.Length; i++) + { + + if (year[i] == 2) + { + y1 += year[i]; + } + + if (year[i] == 3) + { + y2 += year[i]; + } + + } + + sum = y1 + y2; + return sum; + } + public static string ToFarsiYear(this DateTime date) + { + if (date == new DateTime()) return ""; + var pc = new PersianCalendar(); + + return $"{pc.GetYear(date)}"; + } + public static string ToDiscountFormat(this DateTime date) + { + if (date == new DateTime()) return ""; + return $"{date.Year}/{date.Month}/{date.Day}"; + } + + public static string GetTime(this DateTime date) + { + return $"_{date.Hour:00}_{date.Minute:00}_{date.Second:00}"; + } + + public static string ToFarsiFull(this DateTime date) + { + var pc = new PersianCalendar(); + return + $"{pc.GetYear(date)}/{pc.GetMonth(date):00}/{pc.GetDayOfMonth(date):00} {date.Hour:00}:{date.Minute:00}:{date.Second:00}"; + } + + private static readonly string[] Pn = { "۰", "۱", "۲", "۳", "۴", "۵", "۶", "۷", "۸", "۹" }; + private static readonly string[] En = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" }; + + public static string ToEnglishNumber(this string strNum) + { + var cash = strNum; + for (var i = 0; i < 10; i++) + cash = cash.Replace(Pn[i], En[i]); + return cash; + } + + public static string ToPersianNumber(this int intNum) + { + var chash = intNum.ToString(); + for (var i = 0; i < 10; i++) + chash = chash.Replace(En[i], Pn[i]); + return chash; + } + + public static DateTime? FromFarsiDate(this string InDate) + { + if (string.IsNullOrEmpty(InDate)) + return null; + + var spited = InDate.Split('/'); + if (spited.Length < 3) + return null; + + if (!int.TryParse(spited[0].ToEnglishNumber(), out var year)) + return null; + + if (!int.TryParse(spited[1].ToEnglishNumber(), out var month)) + return null; + + if (!int.TryParse(spited[2].ToEnglishNumber(), out var day)) + return null; + var c = new PersianCalendar(); + return c.ToDateTime(year, month, day, 0, 0, 0, 0); + } + + + public static DateTime ToGeorgianDateTime(this string persianDate) + { + try + { + persianDate = persianDate.ToEnglishNumber(); + var year = Convert.ToInt32(persianDate.Substring(0, 4)); + var month = Convert.ToInt32(persianDate.Substring(5, 2)); + var day = Convert.ToInt32(persianDate.Substring(8, 2)); + + return new DateTime(year, month, day, new PersianCalendar()); + + + } + catch (Exception e) + { + return new DateTime(3000, 12, 20, new PersianCalendar()); + } + + } + + public static DateTime ToGeorgian(this string persianDate) + { + persianDate = persianDate.ToEnglishNumber(); + var year = Convert.ToInt32(persianDate.Substring(0, 4)); + var month = 01; + var day = 01; + return new DateTime(year, month, day, new PersianCalendar()); + } + public static string ToMoney(this double myMoney) + { + + return myMoney.ToString("N0", CultureInfo.CreateSpecificCulture("fa-ir")); + } + public static string ToMoneyNullable(this double? myMoney) + { + + return myMoney?.ToString("N0", CultureInfo.CreateSpecificCulture("fa-ir")); + } + public static string ToDoubleMoney(this string myMoney) + { + string bb = string.Empty; + + for (int x = 0; x < myMoney.Length; x++) + { + if (char.IsDigit(myMoney[x])) + bb += myMoney[x]; + } + + if (bb.Length > 0) + { + return bb; + } + else + { + return "0"; + } + + + + } + public static double MoneyToDouble(this string myMoney) + { + string bb = string.Empty; + bool isNegative = false; + + try + { + if (!string.IsNullOrWhiteSpace(myMoney)) + { + for (int x = 0; x < myMoney.Length; x++) + { + if (char.IsDigit(myMoney[x])) + { + bb += myMoney[x]; + } + else if (myMoney[x] == '-' && bb.Length == 0) + { + // اگر علامت منفی قبل از اولین عدد آمد، در نظر بگیر + isNegative = true; + } + } + + if (bb.Length > 0) + { + double res = double.Parse(bb); + return isNegative ? -res : res; + } + else + { + return 0; + } + } + else + { + return 0; + } + + } + catch (Exception) + { + + return 0; + } + } + public static string ToFileName(this DateTime date) + { + return $"{date.Year:0000}-{date.Month:00}-{date.Day:00}-{date.Hour:00}-{date.Minute:00}-{date.Second:00}"; + } + + public static string FindeEndOfMonth(this string date) + { + string y2 = string.Empty; + var year = Convert.ToInt32(date.Substring(0, 4)); + var month = Convert.ToInt32(date.Substring(5, 2)); + var YearD = date.Substring(0, 4); + var MonthD = date.Substring(5, 2); + if (month <= 6) + { + y2 = $"{YearD}/{MonthD}/31"; + } + else if (month > 6 && month < 12) + { + y2 = $"{YearD}/{MonthD}/30"; + } + else if (month == 12) + { + switch (year) + { + case 1346: + y2 = $"{YearD}/{MonthD}/30"; + break; + case 1350: + y2 = $"{YearD}/{MonthD}/30"; + break; + case 1354: + y2 = $"{YearD}/{MonthD}/30"; + break; + case 1358: + y2 = $"{YearD}/{MonthD}/30"; + break; + case 1362: + y2 = $"{YearD}/{MonthD}/30"; + break; + case 1366: + y2 = $"{YearD}/{MonthD}/30"; + break; + case 1370: + y2 = $"{YearD}/{MonthD}/30"; + break; + case 1375: + y2 = $"{YearD}/{MonthD}/30"; + break; + case 1379: + y2 = $"{YearD}/{MonthD}/30"; + break; + case 1383: + y2 = $"{YearD}/{MonthD}/30"; + break; + case 1387: + y2 = $"{YearD}/{MonthD}/30"; + break; + case 1391: + y2 = $"{YearD}/{MonthD}/30"; + break; + case 1395: + y2 = $"{YearD}/{MonthD}/30"; + break; + case 1399: + y2 = $"{YearD}/{MonthD}/30"; + break; + case 1403: + y2 = $"{YearD}/{MonthD}/30"; + break; + case 1408: + y2 = $"{YearD}/{MonthD}/30"; + break; + case 1412: + y2 = $"{YearD}/{MonthD}/30"; + break; + case 1416: + y2 = $"{YearD}/{MonthD}/30"; + break; + case 1420: + y2 = $"{YearD}/{MonthD}/30"; + break; + case 1424: + y2 = $"{YearD}/{MonthD}/30"; + break; + case 1428: + y2 = $"{YearD}/{MonthD}/30"; + break; + case 1432: + y2 = $"{YearD}/{MonthD}/30"; + break; + case 1436: + y2 = $"{YearD}/{MonthD}/30"; + break; + case 1441: + y2 = $"{YearD}/{MonthD}/30"; + break; + case 1445: + y2 = $"{YearD}/{MonthD}/30"; + break; + + default: + y2 = $"{YearD}/{MonthD}/29"; + break; + + } + } + + return y2; + } + + + /// + /// تعداد روزهای سال را برمیگرداند + /// اگر کبیسهد بود سال 366 روزه برمیگرداند + /// اگر کبیسهد نبود سال 365 روزه برمیگرداند + /// + /// + /// + public static int YearTotalDays(this string date) + { + int y2 = 366; + var year = Convert.ToInt32(date.Substring(0, 4)); + + + switch (year) + { + case 1346: + y2 = 367; + break; + case 1350: + y2 = 367; + break; + case 1354: + y2 = 367; + break; + case 1358: + y2 = 367; + break; + case 1362: + y2 = 367; + break; + case 1366: + y2 = 367; + break; + case 1370: + y2 = 367; + break; + case 1375: + y2 = 367; + break; + case 1379: + y2 = 367; + break; + case 1383: + y2 = 367; + break; + case 1387: + y2 = 367; + break; + case 1391: + y2 = 367; + break; + case 1395: + y2 = 367; + break; + case 1399: + y2 = 367; + break; + case 1403: + y2 = 367; + break; + case 1408: + y2 = 367; + break; + case 1412: + y2 = 367; + break; + case 1416: + y2 = 367; + break; + case 1420: + y2 = 367; + break; + case 1424: + y2 = 367; + break; + case 1428: + y2 = 367; + break; + case 1432: + y2 = 367; + break; + case 1436: + y2 = 367; + break; + case 1441: + y2 = 367; + break; + case 1445: + y2 = 367; + break; + + default: + y2 = 366; + break; + + } + + + return y2; + } + + public static int BetweenDateGeorgianToDay(DateTime dateStart, DateTime? dateEnd) + { + DateTime end = DateTime.Now; + if (dateEnd != null) + { + end = (DateTime)dateEnd; + } + return (int)(end - dateStart).TotalDays; + } + + public static string GetMonthByNumber(this string value) + { + + if (value == "01") + { + return "فروردین"; + } + else if (value == "02") + { + return "اردیبهشت"; + } + else if (value == "03") + { + return "خرداد"; + } + else if (value == "04") + { + return "تیر"; + } + else if (value == "05") + { + return "مرداد"; + } + else if (value == "06") + { + return "شهریور"; + } + else if (value == "07") + { + return "مهر"; + } + else if (value == "08") + { + return "آبان"; + } + else if (value == "09") + { + return "آذر"; + } + else if (value == "10") + { + return "دی"; + } + else if (value == "11") + { + return "بهمن"; + } + else + return "اسفند"; + + } + + public static string RestTimeSplit(this string restTime) + { + string result = string.Empty; + + if (restTime?.Length >= 2) + { + result = restTime.Substring(0, 2); + if (result == "00") + result = "0"; + } + else + { + result = "0"; + } + + + return result; + } + + public static string NationalCodeValid(this string nationalCode) + { + try + { + char[] chArray = nationalCode.ToCharArray(); + int[] numArray = new int[chArray.Length]; + var cunt = chArray.Length; + for (int i = 0; i < chArray.Length; i++) + { + numArray[i] = (int)char.GetNumericValue(chArray[i]); + } + + int num2 = numArray[9]; + switch (nationalCode) + { + case "0000000000": + case "1111111111": + case "2222222222": + case "3333333333": + case "4444444444": + case "5555555555": + case "6666666666": + case "7777777777": + case "8888888888": + case "9999999999": + + return "incorrect"; + } + + int num3 = + ((((((((numArray[0] * 10) + (numArray[1] * 9)) + (numArray[2] * 8)) + (numArray[3] * 7)) + + (numArray[4] * 6)) + (numArray[5] * 5)) + (numArray[6] * 4)) + (numArray[7] * 3)) + + (numArray[8] * 2); + int num4 = num3 - ((num3 / 11) * 11); + if ((((num4 == 0) && (num2 == num4)) || ((num4 == 1) && (num2 == 1))) || + ((num4 > 1) && (num2 == Math.Abs((int)(num4 - 11)))) && cunt <= 10) + { + return "valid"; + } + else + { + return "invalid"; + } + } + catch (Exception) + { + return "lessThan10"; + + } + + } + public static string RestTimeMinSplit(this string restTime) + { + string result = string.Empty; + + if (restTime?.Length > 2) + { + result = restTime.Substring(3, 2); + if (result == "00") + result = "0"; + + } + else + { + result = "0"; + } + + + return result; + } + + public static List ExtractNumbers(this string input) + { + List numbers = new List(); + string pattern = @"\d+"; // Matches one or more digits + + MatchCollection matches = Regex.Matches(input, pattern); + + foreach (Match match in matches) + { + if (long.TryParse(match.Value, out long number)) + { + numbers.Add(number); + } + } + + return numbers; + } + public static int ExtractIntNumbers(this string input) + { + int numbers = 0; + string num = ""; + string pattern = @"\d+"; // Matches one or more digits + + MatchCollection matches = Regex.Matches(input, pattern); + + foreach (Match match in matches) + { + if (int.TryParse(match.Value, out int number)) + { + num += $"{number}"; + } + } + + try + { + numbers = Convert.ToInt32(num); + } + catch (Exception e) + { + return 0; + } + + return numbers; + } + public static string ToFarsiMonthByNumber(this string value) + { + if (value == "") return ""; + string result = ""; + switch (value) + { + case "1": + case "01": + result = "فروردین"; + break; + case "2": + case "02": + result = "اردیبهشت"; + break; + case "3": + case "03": + result = "خرداد"; + break; + case "4": + case "04": + result = "تیر"; + break; + case "5": + case "05": + result = "مرداد"; + break; + case "6": + case "06": + result = "شهریور"; + break; + case "7": + case "07": + result = "مهر"; + break; + case "8": + case "08": + result = "آبان"; + break; + case "9": + case "09": + result = "آذر"; + break; + case "10": + result = "دی"; + break; + case "11": + result = "بهمن"; + break; + case "12": + result = "اسفند"; + break; + default: + result = ""; + break; + } + + return result; + } + public static string ToFarsiMonthByIntNumber(this int value) + { + if (value == 0) return ""; + string result = ""; + switch (value) + { + case 1: + result = "فروردین"; + break; + case 2: + result = "اردیبهشت"; + break; + case 3: + result = "خرداد"; + break; + case 4: + result = "تیر"; + break; + case 5: + result = "مرداد"; + break; + case 6: + result = "شهریور"; + break; + case 7: + result = "مهر"; + break; + case 8: + result = "آبان"; + break; + case 9: + result = "آذر"; + break; + case 10: + result = "دی"; + break; + case 11: + result = "بهمن"; + break; + case 12: + result = "اسفند"; + break; + default: + result = ""; + break; + } + + return result; + } + + #region Vafa + public static string ToFarsiWithoutYear(this DateTime date) + { + if (date == new DateTime()) return ""; + var pc = new PersianCalendar(); + return $"{pc.GetMonth(date):00}/{pc.GetDayOfMonth(date):00}"; + } + public static int ToMonthByStringValue(this string value) + { + if (value == "") return 0; + int result = 0; + switch (value) + { + case "فروردین": + result = 1; + break; + case "اردیبهشت": + result = 2; + break; + case "خرداد": + result = 3; + break; + case "تیر": + result = 4; + break; + case "مرداد": + result = 5; + break; + case "شهریور": + result = 6; + break; + case "مهر": + result = 7; + break; + case "آبان": + result = 8; + break; + case "آذر": + result = 9; + break; + case "دی": + result = 10; + break; + case "بهمن": + result = 11; + break; + case "اسفند": + result = 12; + break; + default: + result = 0; + break; + } + + return result; + } + + public static string ColorPercent(this int value) + { + string color = ""; + + var redDark = "#B91C1C"; + var redLight = "#EF4444"; + + var orangeDark = "#F59E0B"; + var orangeLight = "#FBBF24"; + + var limeDark = "#81CB0F"; + var limeLight = "#A3E635"; + + switch (value) + { + case <= 16: + color = redDark; + break; + case <= 33: + color = redLight; + break; + case <= 49: + color = orangeDark; + break; + case <= 66: + color = orangeLight; + break; + case <= 83: + color = limeLight; + break; + case <= 100: + color = limeDark; + break; + default: + color = ""; + break; + } + return color; + } + + public static double RoundMoney(this double value) + { + var valueLength = (((int)value).ToString()).Length; + var checkZero = (((int)value).ToString()).Substring(1, 1); + int digitValue = 0; + int digitLentgh = 0; + int d = 0; + if ((int)value == 10499677) + { + Console.WriteLine(90); + } + switch (valueLength) + { + case 6: + digitValue = 5000; + digitLentgh = 100000; + d = 1000; + break; + case 7: + digitValue = 50000; + digitLentgh = 1000000; + d = 10000; + break; + case 8: + digitValue = checkZero == "0" ? 50000 : 500000; + digitLentgh = checkZero == "0" ? 100000 : 10000000; + d = 100000; + break; + + } + + int result = 0; + int rightDigits = (int)(value % digitLentgh); + + + //if (rightDigits < digitValue) + //{ + // result = (int)(value / d) * d; + //} + //else + //{ + // result = (int)(value / d + 1) * d; + //} + result = (int)(value / d + 1) * d; + return result; + } + + public static string ToMoneyToman(this double myMoney) + { + myMoney = myMoney / 10; + return myMoney.ToString("N0", CultureInfo.CreateSpecificCulture("fa-ir")); + } + + public static PersianDateTime ToPersianDateTime(this DateTime date) + { + var persianDate = date.ToFarsi(); + var year = Convert.ToInt32(persianDate.Substring(0, 4)); + var month = Convert.ToInt32(persianDate.Substring(5, 2)); + var day = Convert.ToInt32(persianDate.Substring(8, 2)); + return new PersianDateTime(year, month, day); + } + + //public static string ResizeImage(string imagePath, int width, int height) + //{ + // using (var srcImage = Image.FromFile(imagePath)) + // { + // var newImage = new Bitmap(width, height); + // using (var graphics = Graphics.FromImage(newImage)) + // { + // graphics.CompositingQuality = CompositingQuality.HighSpeed; + // graphics.InterpolationMode = InterpolationMode.Bicubic; + // graphics.SmoothingMode = SmoothingMode.HighSpeed; + // graphics.DrawImage(srcImage, 0, 0, width, height); + // } + + // using (var memoryStream = new MemoryStream()) + // { + // newImage.Save(memoryStream, ImageFormat.Jpeg); + // return Convert.ToBase64String(memoryStream.ToArray()); + // } + // } + //} + + public static PersianDateTime ToFirstDayOfNextMonth(this DateTime date) + { + var pc = new PersianCalendar(); + var year = pc.GetYear(date); + var month = pc.GetMonth(date); + + if (month == 12) + { + year += 1; + month = 1; + } + else + { + month += 1; + } + + return new PersianDateTime(year, month, 1); + + } + #endregion + + #region Safa + + public static string GetContentTypeImage(string extension) + { + if (!extension.StartsWith(".")) + { + extension = "." + extension; + } + + return extension.ToLower() switch + { + ".jpg" => "image/jpeg", + ".jpeg" => "image/jpeg", + ".png" => "image/png", + ".gif" => "image/gif", + ".bmp" => "image/bmp", + ".svg" => "image/svg+xml", + ".ico" => "image/x-icon", + _ => "", + }; + } + + public static string GetContentType(string extension) + { + + // Ensure the extension starts with a dot + if (!extension.StartsWith(".")) + { + extension = "." + extension; + } + + // Use switch expression to return the appropriate content type + return extension.ToLower() switch + { + ".txt" => "text/plain", + ".htm" => "text/html", + ".html" => "text/html", + ".css" => "text/css", + ".js" => "application/javascript", + ".json" => "application/json", + ".xml" => "application/xml", + ".pdf" => "application/pdf", + ".zip" => "application/zip", + ".rar" => "application/x-rar-compressed", + ".tar" => "application/x-tar", + ".mp3" => "audio/mpeg", + ".wav" => "audio/wav", + ".mp4" => "video/mp4", + ".avi" => "video/x-msvideo", + ".doc" => "application/msword", + ".docx" => "application/vnd.openxmlformats-officedocument.wordprocessingml.document", + ".xls" => "application/vnd.ms-excel", + ".xlsx" => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + ".ppt" => "application/vnd.ms-powerpoint", + ".pptx" => "application/vnd.openxmlformats-officedocument.presentationml.presentation", + _ => "application/octet-stream", + }; + } + + #endregion + public static string ConvertToEnglish(this string value) + { + if (string.IsNullOrEmpty(value)) + return value; + + string EnglishNumbers = ""; + for (int i = 0; i < value.Length; i++) + { + if (Char.IsDigit(value[i])) + { + EnglishNumbers += char.GetNumericValue(value, i); + } + else + { + EnglishNumbers += value[i].ToString(); + } + } + return EnglishNumbers; + } + + public static DateTime ExtractTimeFromDbbackup(this string value) + { + DateTime dateTime = new DateTime(); + var parts = value.Split('-'); + if (parts.Length >= 4 && parts[1].Length == 4 && parts[2].Length == 2 && parts[3].Length == 2 && parts[4].Length == 2 && parts[5].Length >= 2) + { + var part5 = parts[5].Substring(0, 2); + + + try + { + PersianCalendar pc = new PersianCalendar(); + dateTime = pc.ToDateTime(int.Parse(parts[1]), int.Parse(parts[2]), int.Parse(parts[3]), int.Parse(parts[4]), int.Parse(part5), 0, 0, 0); + + } + catch (Exception e) + { + + + } + + } + //var year = value.Substring(10, 4); + //var month = value.Substring(15, 2); + //var day = value.Substring(18, 2); + //var persianDate = year + "/" + month + "/" + day; + //var georgianDate = persianDate.ToGeorgianDateTime(); + //var hourString = value.Substring(21, 2); + //int hour = hourString.ExtractIntNumbers(); + + //var result = new DateTime(georgianDate.Year, georgianDate.Month, georgianDate.Day, hour, 1, 1); + return dateTime; + } + + public static DateTime ExtractTimeFromInsurancebackup(this string value) + { + var year = value.Substring(14, 4); + var month = value.Substring(19, 2); + var day = value.Substring(22, 2); + var persianDate = year + "/" + month + "/" + day; + var georgianDate = persianDate.ToGeorgianDateTime(); + var hourString = value.Substring(25, 2); + int hour = hourString.ExtractIntNumbers(); + + var result = new DateTime(georgianDate.Year, georgianDate.Month, georgianDate.Day, hour, 1, 1); + return result; + } + + public static string FindeEndOfYear(this string date) + { + var year = Convert.ToInt32(date.Substring(0, 4)); + var month = Convert.ToInt32(date.Substring(5, 2)); + var day = Convert.ToInt32(date.Substring(8, 2)); + + var start = new PersianDateTime(year, month, day); + var startAddYear = start.AddMonths(11); + var monthStr = $"{startAddYear.Month}"; + if (monthStr.Length < 2) + monthStr = $"0{monthStr}"; + var lastMonth = $"{startAddYear.Year}/{monthStr}/01"; + var end = lastMonth.FindeEndOfMonth(); + return end; + + } + + public static string CalculateLeaveHoursAndDays(string paidLeaveType, string leaveHourses) + { + string leaveHoursResult = ""; + if (paidLeaveType == "ساعتی") + { + var leaveH = TimeSpan.Parse(leaveHourses); + var hours = (int)leaveH.TotalHours; + var minutes = (int)leaveH.TotalMinutes % 60; + if (hours > 0 && minutes > 0) + { + leaveHoursResult = hours + " ساعت و " + minutes + " دقیقه"; + } + else if (hours > 0 && minutes == 0) + { + leaveHoursResult = hours + " ساعت"; + } + else if (hours == 0 && minutes > 0) + { + leaveHoursResult = minutes + " دقیقه"; + } + } + else + { + leaveHoursResult = leaveHourses + " روز"; + } + + return leaveHoursResult; + } + + public static string ComputationOfHoursAndMinutes(double data) + { + int hours = (int)Math.Floor(data); + double remaining = data - hours; + int minutes = (int)(remaining * 60); + + string result; + if (minutes == 0) + { + result = hours + " س"; + } + else + { + result = hours + " س " + minutes + " د"; + } + + return result; + } + + public static bool CheckValidHm(string input) + { + if (string.IsNullOrWhiteSpace(input)) + return true; + string pattern = @"^([2][0-3]|[1][0-9]|[0-9]|[0][0-9])([:][0-5][0-9])$"; + + var match = Regex.Match(input, pattern); + if (!match.Success) + return false; + return true; + } + + /// + /// چک میکند که در دو شیفت استاتیک تداخل زمانی وجود دارد یا خیر + /// چک میکند که آیا ساعات وارد شده ولید هستند یا خیر + /// + /// + /// + /// + /// + /// + public static bool InterferenceTime(string start1, string end1, string start2, string end2) + { + if (!CheckValidHm(start1)) + return true; + + if (!CheckValidHm(end1)) + return true; + + if (!CheckValidHm(start2)) + return true; + + if (!CheckValidHm(end2)) + return true; + + //اگه دو شیفت نبود + if (string.IsNullOrWhiteSpace(start1) || string.IsNullOrWhiteSpace(start2)) + return false; + + + try + { + var start1Gr = Convert.ToDateTime(start1); + var end1Gr = Convert.ToDateTime(end1); + + if (end1Gr < start1Gr) + end1Gr = end1Gr.AddDays(1); + + var start2Gr = Convert.ToDateTime(start2); + var end2Gr = Convert.ToDateTime(end2); + + + start2Gr = new DateTime(end1Gr.Year, end1Gr.Month, end1Gr.Day, start2Gr.Hour, start2Gr.Minute, + start2Gr.Second); + + + end2Gr = new DateTime(end1Gr.Year, end1Gr.Month, end1Gr.Day, end2Gr.Hour, end2Gr.Minute, + end2Gr.Second); + if (end2Gr < start2Gr) + end2Gr = end2Gr.AddDays(1); + + var diff = (end1Gr - start1Gr).Add((end2Gr - start2Gr)); + if (diff > new TimeSpan(24,0,0)) + return true; + + if (start2Gr <= end1Gr) + return true; + + return false; + } + catch (Exception) + { + + return true; + } + + + } + public static DateTime FindFirstDayOfMonthGr(this DateTime date) + { + var pc = new PersianCalendar(); + return ($"{pc.GetYear(date)}/{pc.GetMonth(date):00}/01").ToGeorgianDateTime(); + } + #region Mahan + + + public static bool IsvalidIban(this string iban) + { + return Regex.IsMatch(iban, @"^IR[0-9]{24}$"); + } + public static bool IsValidCardNumber(this string cardNumber) + { + return Regex.IsMatch(cardNumber, @"^[0-9]{16}$"); + } + /// + /// این متد حروف عربی را به فارسی در میاورد. مثال: علي را به علی تبدیل میکند + /// + /// + /// + public static string ToPersian(this string text) + { + var res = ""; + foreach (var @char in text) + { + + if (@char == char.Parse("ي")) + res += "ی"; + else if (@char == char.Parse("ك")) + res += "ک"; + else + res += @char; + } + return res; + } + + /// + /// این متد سعی میکند رشته را به تاریخ برگرداند و یک بول و دیت تایم برمیگرداند + /// + /// تاریخ شمسی + /// تاریخ + /// + public static bool TryToGeorgianDateTime(this string persianDate, out DateTime georgianDateTime) + { + if (string.IsNullOrWhiteSpace(persianDate)) + { + georgianDateTime = new DateTime(3000, 12, 20, new PersianCalendar()); + return false; + } + persianDate = persianDate.ToEnglishNumber(); + try + { + var year = Convert.ToInt32(persianDate.Substring(0, 4)); + var month = Convert.ToInt32(persianDate.Substring(5, 2)); + var day = Convert.ToInt32(persianDate.Substring(8, 2)); + + georgianDateTime = new DateTime(year, month, day, new PersianCalendar()); + return true; + } + catch + { + georgianDateTime = new DateTime(3000, 12, 20, new PersianCalendar()); + return false; + } + } + + public static string FindFirstDayOfMonth(this DateTime date) + { + var pc = new PersianCalendar(); + return $"{pc.GetYear(date)}/{pc.GetMonth(date):00}/01"; + } + public static string ToFarsiDuration(this string date) + { + var today = DateTime.Now.ToFarsi(); + var year = Convert.ToInt32(today.Substring(0, 4)); + var month = Convert.ToInt32(today.Substring(5, 2)); + var day = Convert.ToInt32(today.Substring(8, 2)); + var todayPersianDate = new PersianDateTime(year, month, day); + + var planYear = Convert.ToInt32(date.Substring(0, 4)); + var planMonth = Convert.ToInt32(date.Substring(5, 2)); + var planDay = Convert.ToInt32(date.Substring(8, 2)); + var planPersianDate = new PersianDateTime(planYear, planMonth, planDay); + + if (planPersianDate > todayPersianDate) + { + var countDay = 0; + var counMonth = 0; + var nextMonth = new PersianDateTime(todayPersianDate).AddMonths(1); + for (var start = todayPersianDate; start <= planPersianDate; start = start.AddDays(1)) + { + countDay++; + if (start == nextMonth) + { + counMonth++; + nextMonth = new PersianDateTime(start).AddMonths(1); + countDay = 0; + } + } + + if (counMonth > 0) + { + if (countDay == 0) + { + return $"{counMonth} ماه"; + } + return $"{counMonth}ماه و {countDay} روز"; + } + else + { + return $"{countDay}روز"; + } + } + else + { + return ""; + } + } + + public static string ToFarsiDuration2(this string date) + { + var persianCalendar = new System.Globalization.PersianCalendar(); + var today = DateTime.Now; + + // Convert today's Gregorian date to Persian date + var todayYear = persianCalendar.GetYear(today); + var todayMonth = persianCalendar.GetMonth(today); + var todayDay = persianCalendar.GetDayOfMonth(today); + + var todayPersianDate = new DateTime(todayYear, todayMonth, todayDay, persianCalendar); + + // Parse the target Persian date from the input string + var planYear = int.Parse(date.Substring(0, 4)); + var planMonth = int.Parse(date.Substring(5, 2)); + var planDay = int.Parse(date.Substring(8, 2)); + + var planPersianDate = new DateTime(planYear, planMonth, planDay, persianCalendar); + + if (planPersianDate > todayPersianDate) + { + // Calculate the exact difference in years, months, and days + int yearDifference = planYear - todayYear; + int monthDifference = planMonth - todayMonth; + int dayDifference = planDay - todayDay; + + if (dayDifference < 0) + { + monthDifference--; + dayDifference += persianCalendar.GetDaysInMonth(todayYear, todayMonth); + } + + if (monthDifference < 0) + { + yearDifference--; + monthDifference += 12; + } + + // Construct the duration string + var duration = ""; + if (yearDifference > 0) + { + duration += $"{yearDifference} سال "; + } + + if (monthDifference > 0) + { + duration += $"{monthDifference} ماه "; + } + + if (dayDifference > 0) + { + duration += $"{dayDifference} روز"; + } + + return duration.Trim(); + } + else + { + return ""; + } + } + //public static string SerializeToBson(object obj) + //{ + // using var memoryStream = new MemoryStream(); + // using (BsonDataWriter bsonWriter = new BsonDataWriter(memoryStream)) + // { + // JsonSerializer serializer = new JsonSerializer(); + // serializer.Serialize(bsonWriter, obj); + // } + // byte[] bsonData = memoryStream.ToArray(); + // return Convert.ToBase64String(bsonData); + //} + ////بیسان هایی که بصورت لیست بودند استخراج میشود + //public static List DeserializeFromBsonList(string base64Data) + //{ + // byte[] data = Convert.FromBase64String(base64Data); + + // using MemoryStream memoryStream = new MemoryStream(data); + // using BsonDataReader reader = new BsonDataReader(memoryStream); + // reader.ReadRootValueAsArray = true; + // JsonSerializer serializer = new JsonSerializer(); + // return serializer.Deserialize>(reader); + //} + ////بیسان هایی که بصورت تکی بودند استخراج میشود + //public static T DeserializeFromBson(string base64Data) + //{ + // byte[] bsonData = Convert.FromBase64String(base64Data); + // using MemoryStream memoryStream = new MemoryStream(bsonData); + // using BsonDataReader bsonReader = new BsonDataReader(memoryStream); + // JsonSerializer serializer = new JsonSerializer(); + // return serializer.Deserialize(bsonReader); + //} + + //public static TimeOnly CalculateOffset(ICollection shiftDetailsRegularShifts) + //{ + // if (!shiftDetailsRegularShifts.Any()) + // { + // return TimeOnly.MinValue; + // } + // var date = new DateOnly(); + // var firstStartShift = new DateTime(date, shiftDetailsRegularShifts.MinBy(x => x.Placement).StartTime); + // var lastEndShift = new DateTime(date, shiftDetailsRegularShifts.MaxBy(x => x.Placement).EndTime); + // if (lastEndShift > firstStartShift) + // firstStartShift = firstStartShift.AddDays(1); + // var offSet = (firstStartShift - lastEndShift).Divide(2); + // return TimeOnly.FromDateTime(lastEndShift.Add(offSet)); + //} + public static DateTime GetNextDayOfWeek(this DateTime date, DayOfWeek dayOfWeek) + { + int numberOfNextDayOfWeek = ((int)dayOfWeek - (int)date.DayOfWeek + 7) % 7; + return date.AddDays(numberOfNextDayOfWeek == 0 ? 7 : numberOfNextDayOfWeek); + } + + + //این متد آخر همان روز را به صورت دیت تایم برمیگرداند + public static DateTime ToEndDayOfGeorgianDateTime(this string persianDate) + { + persianDate = persianDate.ToEnglishNumber(); + try + { + var year = Convert.ToInt32(persianDate.Substring(0, 4)); + var month = Convert.ToInt32(persianDate.Substring(5, 2)); + var day = Convert.ToInt32(persianDate.Substring(8, 2)); + + var res = new DateTime(year, month, day, new PersianCalendar()); + res = res.AddHours(23); + res = res.AddMinutes(59); + res = res.AddSeconds(59); + + return res; + + } + catch (Exception e) + { + return new DateTime(3000, 12, 20, new PersianCalendar()); + } + + } + //تبدیل به تاریخ با ساعت + public static DateTime ToGeorgianDateWithTime(this string persianDate, string persianTime) + { + persianDate = persianDate.ToEnglishNumber(); + try + { + var year = Convert.ToInt32(persianDate.Substring(0, 4)); + var month = Convert.ToInt32(persianDate.Substring(5, 2)); + var day = Convert.ToInt32(persianDate.Substring(8, 2)); + + + + var hour = int.Parse(persianTime.Substring(0, 2)); + var minute = int.Parse(persianTime.Substring(3, 2)); + + var res = new DateTime(year, month, day, new PersianCalendar()); + res = res.AddHours(hour); + res = res.AddMinutes(minute); + return res; + + } + catch (Exception e) + { + return new DateTime(3000, 12, 20, new PersianCalendar()); + } + + } + + public static string DayOfWeeKToPersian(this DayOfWeek dayOfWeek) + { + return dayOfWeek switch + { + DayOfWeek.Friday => "جمعه", + DayOfWeek.Monday => "دوشنبه", + DayOfWeek.Saturday => "شنبه", + DayOfWeek.Sunday => "یکشنبه", + DayOfWeek.Thursday => "پنجشنبه", + DayOfWeek.Tuesday => "سه شنبه", + DayOfWeek.Wednesday => "چهارشنبه", + _ => "" + }; + } + + public static bool IsInvalidDateTime(this DateTime date) + { + return date == new DateTime(3000, 12, 20, new PersianCalendar()); + + } + + + + + + #endregion + + #region Pooya + /// + /// محاسبه روز های هر ماه شمسی + /// + /// تاریخ روزی از ماه + public static int CountPersianMonthDays(this DateTime date) + { + DateTime currentMonthDate, nextMonthDate; + currentMonthDate = date.FindFirstDayOfMonth().ToGeorgianDateTime(); + FindFirstDayOfNextMonth(date, out nextMonthDate); + + return ((int)(nextMonthDate.Date - currentMonthDate.Date).TotalDays); + } + + public static string FindFirstDayOfNextMonth(this DateTime date, out DateTime nextMonthDate) + { + var dateFa = date.ToFarsi(); + int year = Convert.ToInt32(dateFa.Substring(0, 4)); + int month = Convert.ToInt32(dateFa.Substring(5, 2)); + int nextMonth; + int nextMonthYear; + if (month == 12) + { + nextMonthYear = year + 1; + nextMonth = 1; + } + else + { + nextMonthYear = year; + nextMonth = month + 1; + } + nextMonthDate = new DateTime(nextMonthYear, nextMonth, 1, new PersianCalendar()); + return $"{nextMonthYear:0000}/{nextMonth:00}/01"; + } + + + /// + /// اضافه یا کم کردن ماه، توجه داشته باشید خروجی متد همیشه یکم ماه می باشد + /// + public static string AddMonthsFa(this DateTime date, int count, out DateTime result) + { + var dateFa = date.ToFarsi(); + int year = Convert.ToInt32(dateFa.Substring(0, 4)); + int month = Convert.ToInt32(dateFa.Substring(5, 2)); + + int newMonth; + int newYear; + + //add operation + if (count >= 0) + { + newYear = year; + while (month + count > 12) + { + newYear += 1; + count -= 12; + } + newMonth = month + count; + + } + + //subtract operation + else + { + newYear = year; + while (month + count < 1) + { + newYear -= 1; + count += 12; + } + newMonth = month + count; + } + result = new DateTime(newYear, newMonth, 1, new PersianCalendar()); + return $"{newYear:0000}/{newMonth:00}/01"; + + } + + + public static DateTime GetUndefinedDateTime() + { + return new DateTime(2121, 03, 21); + } + + public static bool IsDateUndefined(this DateTime date) + { + return date == new DateTime(2121, 03, 21); + } + public static string ToFarsiHoursAndMinutes(int hours, int minutes, string emptyValue = "") + { + + string message = emptyValue; + if (hours > 0 && minutes > 0) + { + + message = hours + " " + "ساعت و" + " " + minutes + " " + "دقیقه"; + } + else if (hours > 0 && minutes == 0) + { + + message = hours + " " + "ساعت "; + } + else if (hours == 0 && minutes > 0) + { + + message = minutes + " " + "دقیقه"; + } + + return message; + } + /// + /// تبدیل بازه زمانی اینتیجر به متن ساعت و دقسقه + /// + /// + /// + /// + public static string ConvertIntDurationToHoursAndMinutes(this int duration, string emptyValue = "") + { + var minutes = duration % 60; + var hours = duration / 60; + + string message = emptyValue; + if (hours > 0 && minutes > 0) + { + + message = hours + " " + "ساعت و" + " " + minutes + " " + "دقیقه"; + } + else if (hours > 0 && minutes == 0) + { + + message = hours + " " + "ساعت "; + } + else if (hours == 0 && minutes > 0) + { + + message = minutes + " " + "دقیقه"; + } + + return message; + } + + public static string ToFarsiHoursAndMinutes(this TimeSpan timeSpan, string emptyValue = "") + { + var hours = (int)timeSpan.TotalHours; + var minutes = timeSpan.Minutes; + string message = emptyValue; + if (hours > 0 && minutes > 0) + { + + message = hours + " " + "ساعت و" + " " + minutes + " " + "دقیقه"; + } + else if (hours > 0 && minutes == 0) + { + + message = hours + " " + "ساعت "; + } + else if (hours == 0 && minutes > 0) + { + + message = minutes + " " + "دقیقه"; + } + + return message; + } + public static string ToFarsiDaysAndHoursAndMinutes(this TimeSpan timeSpan, string emptyValue = "") + { + var hours = (int)timeSpan.TotalHours; + var minutes = timeSpan.Minutes; + var days = hours / 24; + hours = hours % 24; + string message = ""; + + if (days > 0) + message += days + " " + "روز"; + if (hours > 0) + if (message == "") + message += hours + " " + "ساعت"; + else + message += " و " + hours + " " + "ساعت"; + if (minutes > 0) + if (message == "") + message += minutes + " " + "دقیقه"; + else + message += " و " + minutes + " " + "دقیقه"; + + if (message == "") + message = emptyValue; + return message; + } + + public static bool ArePropertiesEqual(this T obj1, T obj2) + { + // If either object is null, they can't be equal + if (obj1 == null || obj2 == null) + return false; + + // Get the type of the objects + var type = typeof(T); + + // Iterate through each property + foreach (var property in type.GetProperties()) + { + // Get the values of the current property for both objects + var value1 = property.GetValue(obj1); + var value2 = property.GetValue(obj2); + + // If both values are null, they are considered equal + if (value1 == null && value2 == null) + continue; + + // If one value is null, but the other isn't, they are not equal + if (value1 == null || value2 == null) + return false; + + // If values are not equal, return false + if (!value1.Equals(value2)) + return false; + } + + // If all properties are equal, return true + return true; + } + + #endregion + + #region Davoodi + + //public static List GetDaysBetweenDateGeorgian(DateTime startDate, DateTime? endDate) + //{ + // var days = new List(); + + // if (endDate == null) + // endDate = DateTime.Now; + + // var persianStartDate = new MD.PersianDateTime.Standard.PersianDateTime(startDate); + // var persianEndDate = new MD.PersianDateTime.Standard.PersianDateTime(endDate); + + + // while (persianEndDate - persianStartDate >= TimeSpan.FromDays(0)) + // { + // days.Add(persianStartDate.ToShortDateString()); + // persianStartDate = persianStartDate.AddDays(1); + // } + + // return days; + //} + + public static int GetWorkingDaysDifference(DateTime? fromDate, DateTime? toDate) + { + //var workingDays = PersianDateExtensions.GetWorkingDays(new PersianDateTime(fromDate.ToFarsi()), new PersianDateTime(toDate.ToFarsi()), true); + var workingDays = PersianDateExtensions.GetWorkingDays((DateTime)fromDate, (DateTime)toDate, true); + + + if (fromDate > toDate) + workingDays *= -1; + + + return workingDays; + } + + + + #endregion +} \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/ValueObject.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/ValueObject.cs new file mode 100644 index 00000000..9a486daa --- /dev/null +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/_Common/ValueObject.cs @@ -0,0 +1,38 @@ +namespace GozareshgirProgramManager.Domain._Common; + +public abstract class ValueObject +{ + protected abstract IEnumerable GetEqualityComponents(); + + public override bool Equals(object? obj) + { + if (obj == null || obj.GetType() != GetType()) + return false; + + var other = (ValueObject)obj; + return GetEqualityComponents().SequenceEqual(other.GetEqualityComponents()); + } + + public override int GetHashCode() + { + return GetEqualityComponents() + .Select(x => x?.GetHashCode() ?? 0) + .Aggregate((x, y) => x ^ y); + } + + public static bool operator ==(ValueObject? left, ValueObject? right) + { + if (left is null && right is null) + return true; + + if (left is null || right is null) + return false; + + return left.Equals(right); + } + + public static bool operator !=(ValueObject? left, ValueObject? right) + { + return !(left == right); + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/DependencyInjection.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/DependencyInjection.cs new file mode 100644 index 00000000..8451e848 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/DependencyInjection.cs @@ -0,0 +1,109 @@ + + + +using FluentValidation; +using GozareshgirProgramManager.Application._Common.Behaviors; +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.CheckoutAgg.Repositories; +using GozareshgirProgramManager.Domain.CustomerAgg.Repositories; +using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; +using GozareshgirProgramManager.Domain.RoleAgg.Repositories; +using GozareshgirProgramManager.Domain.RoleAgg.Repositories; +using GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Repositories; +using GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Repositories; +using GozareshgirProgramManager.Domain.SkillAgg.Repositories; +using GozareshgirProgramManager.Domain.SkillAgg.Repositories; +using GozareshgirProgramManager.Domain.UserAgg.Repositories; +using GozareshgirProgramManager.Infrastructure.Persistence; +using GozareshgirProgramManager.Infrastructure.Persistence.Context; +using GozareshgirProgramManager.Infrastructure.Persistence.Repositories; +using GozareshgirProgramManager.Infrastructure.Services.Authentication; +using GozareshgirProgramManager.Infrastructure.Services.Role; +using GozareshgirProgramManager.Infrastructure.Services.User; +using MediatR; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Shared.Contracts.PmRole.Commands; +using Shared.Contracts.PmRole.Queries; +using Shared.Contracts.PmUser; + +namespace GozareshgirProgramManager.Infrastructure; + +public static class DependencyInjection +{ + public static IServiceCollection AddProgramManagerInfrastructure( + this IServiceCollection services, + IConfiguration configuration) + { + // DbContext + services.AddDbContext(options => + options.UseSqlServer( + configuration.GetConnectionString("ProgramManagerDb"), + b => b.MigrationsAssembly(typeof(ProgramManagerDbContext).Assembly.FullName))); + + // Register IAppDbContext + services.AddScoped(provider => + provider.GetRequiredService()); + + + // Unit of Work + services.AddScoped(); + + //Users + services.AddScoped(); + + //Roles + services.AddScoped(); + + //WorkingHours + services.AddScoped(); + + //Checkout + services.AddScoped(); + + // Repositories + services.AddScoped(); + + // Legacy Project repositories + services.AddScoped(); + + // New Hierarchy repositories + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + + services.AddScoped(); + + services.AddScoped(); + + // JWT Settings + services.Configure(configuration.GetSection("JwtSettings")); + + // Authentication Services + services.AddScoped(); + services.AddScoped(); + + + + #region ServicesInjection + + services.AddTransient(); + + services.AddTransient(); + services.AddTransient(); + + #endregion + + + // MediatR Validation Behavior + services.AddTransient(typeof(IPipelineBehavior<,>), typeof(ValidationBehavior<,>)); + + + return services; + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/GozareshgirProgramManager.Infrastructure.csproj b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/GozareshgirProgramManager.Infrastructure.csproj new file mode 100644 index 00000000..63dd5c8a --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/GozareshgirProgramManager.Infrastructure.csproj @@ -0,0 +1,25 @@ + + + + net10.0 + enable + enable + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251119114157_Initial.Designer.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251119114157_Initial.Designer.cs new file mode 100644 index 00000000..45ff290c --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251119114157_Initial.Designer.cs @@ -0,0 +1,393 @@ +// +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("20251119114157_Initial")] + partial class Initial + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.22") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.CustomerAgg.Customer", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("Customers", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.AdditionalTime", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AddedAt") + .HasColumnType("datetime2"); + + b.Property("AddedByUserId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Hours") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("Reason") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("TaskSectionId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("TaskSectionId"); + + b.ToTable("AdditionalTimes", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("Projects", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AllocatedTime") + .HasColumnType("time"); + + b.Property("AssignedUserId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("HasAssignmentOverride") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("HasTimeOverride") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("Level") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ParentId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("Level"); + + b.HasIndex("ParentId"); + + b.HasIndex("Level", "AssignedUserId"); + + b.ToTable("ProjectNodes", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ProjectId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.ToTable("ProjectPhases", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("PhaseId") + .HasColumnType("uniqueidentifier"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.HasIndex("PhaseId"); + + b.ToTable("ProjectTasks", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AllocatedTime") + .HasColumnType("time"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("CurrentAssignedUserId") + .HasColumnType("bigint"); + + b.Property("InitialEstimatedHours") + .HasColumnType("time"); + + b.Property("ProjectTaskId") + .HasColumnType("uniqueidentifier"); + + b.Property("SectionType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("TaskNodeId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("ProjectTaskId"); + + b.HasIndex("TaskNodeId"); + + b.ToTable("TaskSections", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSectionActivity", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("EndNotes") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("Notes") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("SectionId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("SectionId"); + + b.ToTable("TaskSectionActivities", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.AdditionalTime", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", null) + .WithMany("AdditionalTimes") + .HasForeignKey("TaskSectionId"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", "Parent") + .WithMany("Children") + .HasForeignKey("ParentId") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("Parent"); + }); + + 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.ProjectTask", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", "ProjectPhase") + .WithMany("Tasks") + .HasForeignKey("PhaseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ProjectPhase"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", null) + .WithMany("Sections") + .HasForeignKey("ProjectTaskId"); + + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", "TaskNode") + .WithMany("Sections") + .HasForeignKey("TaskNodeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("TaskNode"); + }); + + 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.Project", b => + { + b.Navigation("Phases"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", b => + { + b.Navigation("Children"); + + b.Navigation("Sections"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", b => + { + 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"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251119114157_Initial.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251119114157_Initial.cs new file mode 100644 index 00000000..546082b6 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251119114157_Initial.cs @@ -0,0 +1,262 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace GozareshgirProgramManager.Infrastructure.Migrations +{ + /// + public partial class Initial : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Customers", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + Name = table.Column(type: "nvarchar(200)", maxLength: 200, nullable: false), + Email = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + CreatedAt = table.Column(type: "datetime2", nullable: false), + CreationDate = table.Column(type: "datetime2", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Customers", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "ProjectNodes", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + Name = table.Column(type: "nvarchar(200)", maxLength: 200, nullable: false), + Description = table.Column(type: "nvarchar(1000)", maxLength: 1000, nullable: true), + Level = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: false), + ParentId = table.Column(type: "uniqueidentifier", nullable: true), + AllocatedTime = table.Column(type: "time", nullable: true), + AssignedUserId = table.Column(type: "bigint", nullable: true), + HasTimeOverride = table.Column(type: "bit", nullable: false, defaultValue: false), + HasAssignmentOverride = table.Column(type: "bit", nullable: false, defaultValue: false), + CreationDate = table.Column(type: "datetime2", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ProjectNodes", x => x.Id); + table.ForeignKey( + name: "FK_ProjectNodes_ProjectNodes_ParentId", + column: x => x.ParentId, + principalTable: "ProjectNodes", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "Projects", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + Name = table.Column(type: "nvarchar(200)", maxLength: 200, nullable: false), + Description = table.Column(type: "nvarchar(1000)", maxLength: 1000, nullable: true), + CreationDate = table.Column(type: "datetime2", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Projects", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "ProjectPhases", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + Name = table.Column(type: "nvarchar(200)", maxLength: 200, nullable: false), + Description = table.Column(type: "nvarchar(1000)", maxLength: 1000, nullable: true), + ProjectId = table.Column(type: "uniqueidentifier", nullable: false), + CreationDate = table.Column(type: "datetime2", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ProjectPhases", x => x.Id); + table.ForeignKey( + name: "FK_ProjectPhases_Projects_ProjectId", + column: x => x.ProjectId, + principalTable: "Projects", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ProjectTasks", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + Name = table.Column(type: "nvarchar(200)", maxLength: 200, nullable: false), + Description = table.Column(type: "nvarchar(1000)", maxLength: 1000, nullable: true), + PhaseId = table.Column(type: "uniqueidentifier", nullable: false), + Status = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: false), + CreationDate = table.Column(type: "datetime2", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ProjectTasks", x => x.Id); + table.ForeignKey( + name: "FK_ProjectTasks_ProjectPhases_PhaseId", + column: x => x.PhaseId, + principalTable: "ProjectPhases", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "TaskSections", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + TaskNodeId = table.Column(type: "uniqueidentifier", nullable: false), + SectionType = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: false), + InitialEstimatedHours = table.Column(type: "time", nullable: false), + Status = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: false), + CurrentAssignedUserId = table.Column(type: "bigint", nullable: true), + AllocatedTime = table.Column(type: "time", nullable: true), + ProjectTaskId = table.Column(type: "uniqueidentifier", nullable: true), + CreationDate = table.Column(type: "datetime2", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_TaskSections", x => x.Id); + table.ForeignKey( + name: "FK_TaskSections_ProjectNodes_TaskNodeId", + column: x => x.TaskNodeId, + principalTable: "ProjectNodes", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_TaskSections_ProjectTasks_ProjectTaskId", + column: x => x.ProjectTaskId, + principalTable: "ProjectTasks", + principalColumn: "Id"); + }); + + migrationBuilder.CreateTable( + name: "AdditionalTimes", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + Hours = table.Column(type: "nvarchar(30)", maxLength: 30, nullable: false), + Reason = table.Column(type: "nvarchar(1000)", maxLength: 1000, nullable: true), + AddedByUserId = table.Column(type: "bigint", nullable: true), + AddedAt = table.Column(type: "datetime2", nullable: false), + TaskSectionId = table.Column(type: "uniqueidentifier", nullable: true), + CreationDate = table.Column(type: "datetime2", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AdditionalTimes", x => x.Id); + table.ForeignKey( + name: "FK_AdditionalTimes_TaskSections_TaskSectionId", + column: x => x.TaskSectionId, + principalTable: "TaskSections", + principalColumn: "Id"); + }); + + migrationBuilder.CreateTable( + name: "TaskSectionActivities", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + SectionId = table.Column(type: "uniqueidentifier", nullable: false), + UserId = table.Column(type: "bigint", nullable: false), + StartDate = table.Column(type: "datetime2", nullable: false), + EndDate = table.Column(type: "datetime2", nullable: true), + Notes = table.Column(type: "nvarchar(1000)", maxLength: 1000, nullable: true), + EndNotes = table.Column(type: "nvarchar(1000)", maxLength: 1000, nullable: true), + CreationDate = table.Column(type: "datetime2", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_TaskSectionActivities", x => x.Id); + table.ForeignKey( + name: "FK_TaskSectionActivities_TaskSections_SectionId", + column: x => x.SectionId, + principalTable: "TaskSections", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_AdditionalTimes_TaskSectionId", + table: "AdditionalTimes", + column: "TaskSectionId"); + + migrationBuilder.CreateIndex( + name: "IX_ProjectNodes_Level", + table: "ProjectNodes", + column: "Level"); + + migrationBuilder.CreateIndex( + name: "IX_ProjectNodes_Level_AssignedUserId", + table: "ProjectNodes", + columns: new[] { "Level", "AssignedUserId" }); + + migrationBuilder.CreateIndex( + name: "IX_ProjectNodes_ParentId", + table: "ProjectNodes", + column: "ParentId"); + + migrationBuilder.CreateIndex( + name: "IX_ProjectPhases_ProjectId", + table: "ProjectPhases", + column: "ProjectId"); + + migrationBuilder.CreateIndex( + name: "IX_ProjectTasks_PhaseId", + table: "ProjectTasks", + column: "PhaseId"); + + migrationBuilder.CreateIndex( + name: "IX_TaskSectionActivities_SectionId", + table: "TaskSectionActivities", + column: "SectionId"); + + migrationBuilder.CreateIndex( + name: "IX_TaskSections_ProjectTaskId", + table: "TaskSections", + column: "ProjectTaskId"); + + migrationBuilder.CreateIndex( + name: "IX_TaskSections_TaskNodeId", + table: "TaskSections", + column: "TaskNodeId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "AdditionalTimes"); + + migrationBuilder.DropTable( + name: "Customers"); + + migrationBuilder.DropTable( + name: "TaskSectionActivities"); + + migrationBuilder.DropTable( + name: "TaskSections"); + + migrationBuilder.DropTable( + name: "ProjectNodes"); + + migrationBuilder.DropTable( + name: "ProjectTasks"); + + migrationBuilder.DropTable( + name: "ProjectPhases"); + + migrationBuilder.DropTable( + name: "Projects"); + } + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251119152314_ChangeUsertable.Designer.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251119152314_ChangeUsertable.Designer.cs new file mode 100644 index 00000000..e78e8c7c --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251119152314_ChangeUsertable.Designer.cs @@ -0,0 +1,320 @@ +// +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("20251119152314_ChangeUsertable")] + partial class ChangeUsertable + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.22") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.CustomerAgg.Customer", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("Customers", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AllocatedTime") + .HasColumnType("time"); + + b.Property("AssignedUserId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("HasAssignmentOverride") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("HasTimeOverride") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("Level") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ParentId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("Level"); + + b.HasIndex("ParentId"); + + b.HasIndex("Level", "AssignedUserId"); + + b.ToTable("ProjectNodes", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AllocatedTime") + .HasColumnType("time"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("CurrentAssignedUserId") + .HasColumnType("bigint"); + + b.Property("InitialEstimatedHours") + .HasColumnType("time"); + + b.Property("SectionType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("TaskNodeId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("TaskNodeId"); + + b.ToTable("TaskSections", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSectionActivity", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("EndNotes") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("Notes") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("SectionId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("SectionId"); + + b.ToTable("TaskSectionActivities", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSectionAdditionalTime", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AddedAt") + .HasColumnType("datetime2"); + + b.Property("AddedByUserId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Hours") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("ProjectSectionId") + .HasColumnType("uniqueidentifier"); + + b.Property("Reason") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.HasKey("Id"); + + b.HasIndex("ProjectSectionId"); + + b.ToTable("AdditionalTimes", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .HasMaxLength(150) + .HasColumnType("nvarchar(150)"); + + b.Property("FullName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("Mobile") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.Property("Password") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("ProfilePhotoPath") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("VerifyCode") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.HasKey("Id"); + + b.ToTable("Users", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", "Parent") + .WithMany("Children") + .HasForeignKey("ParentId") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("Parent"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", "TaskNode") + .WithMany("Sections") + .HasForeignKey("TaskNodeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("TaskNode"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSectionActivity", 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.ProjectSectionAdditionalTime", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", null) + .WithMany("AdditionalTimes") + .HasForeignKey("ProjectSectionId"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", b => + { + b.Navigation("Children"); + + b.Navigation("Sections"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.Navigation("Activities"); + + b.Navigation("AdditionalTimes"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251119152314_ChangeUsertable.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251119152314_ChangeUsertable.cs new file mode 100644 index 00000000..334e7d78 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251119152314_ChangeUsertable.cs @@ -0,0 +1,192 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace GozareshgirProgramManager.Infrastructure.Migrations +{ + /// + public partial class ChangeUsertable : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_AdditionalTimes_TaskSections_TaskSectionId", + table: "AdditionalTimes"); + + migrationBuilder.DropForeignKey( + name: "FK_TaskSections_ProjectTasks_ProjectTaskId", + table: "TaskSections"); + + migrationBuilder.DropTable( + name: "ProjectTasks"); + + migrationBuilder.DropTable( + name: "ProjectPhases"); + + migrationBuilder.DropTable( + name: "Projects"); + + migrationBuilder.DropIndex( + name: "IX_TaskSections_ProjectTaskId", + table: "TaskSections"); + + migrationBuilder.DropColumn( + name: "ProjectTaskId", + table: "TaskSections"); + + migrationBuilder.RenameColumn( + name: "TaskSectionId", + table: "AdditionalTimes", + newName: "ProjectSectionId"); + + migrationBuilder.RenameIndex( + name: "IX_AdditionalTimes_TaskSectionId", + table: "AdditionalTimes", + newName: "IX_AdditionalTimes_ProjectSectionId"); + + migrationBuilder.CreateTable( + name: "Users", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + FullName = table.Column(type: "nvarchar(100)", maxLength: 100, nullable: false), + UserName = table.Column(type: "nvarchar(100)", maxLength: 100, nullable: false), + Password = table.Column(type: "nvarchar(1000)", maxLength: 1000, nullable: false), + ProfilePhotoPath = table.Column(type: "nvarchar(500)", maxLength: 500, nullable: true), + Mobile = table.Column(type: "nvarchar(20)", maxLength: 20, nullable: false), + Email = table.Column(type: "nvarchar(150)", maxLength: 150, nullable: true), + IsActive = table.Column(type: "bit", nullable: false), + VerifyCode = table.Column(type: "nvarchar(10)", maxLength: 10, nullable: true), + AccountId = table.Column(type: "bigint", nullable: true), + CreationDate = table.Column(type: "datetime2", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Users", x => x.Id); + }); + + migrationBuilder.AddForeignKey( + name: "FK_AdditionalTimes_TaskSections_ProjectSectionId", + table: "AdditionalTimes", + column: "ProjectSectionId", + principalTable: "TaskSections", + principalColumn: "Id"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_AdditionalTimes_TaskSections_ProjectSectionId", + table: "AdditionalTimes"); + + migrationBuilder.DropTable( + name: "Users"); + + migrationBuilder.RenameColumn( + name: "ProjectSectionId", + table: "AdditionalTimes", + newName: "TaskSectionId"); + + migrationBuilder.RenameIndex( + name: "IX_AdditionalTimes_ProjectSectionId", + table: "AdditionalTimes", + newName: "IX_AdditionalTimes_TaskSectionId"); + + migrationBuilder.AddColumn( + name: "ProjectTaskId", + table: "TaskSections", + type: "uniqueidentifier", + nullable: true); + + migrationBuilder.CreateTable( + name: "Projects", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + CreationDate = table.Column(type: "datetime2", nullable: false), + Description = table.Column(type: "nvarchar(1000)", maxLength: 1000, nullable: true), + Name = table.Column(type: "nvarchar(200)", maxLength: 200, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Projects", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "ProjectPhases", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + ProjectId = table.Column(type: "uniqueidentifier", nullable: false), + CreationDate = table.Column(type: "datetime2", nullable: false), + Description = table.Column(type: "nvarchar(1000)", maxLength: 1000, nullable: true), + Name = table.Column(type: "nvarchar(200)", maxLength: 200, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ProjectPhases", x => x.Id); + table.ForeignKey( + name: "FK_ProjectPhases_Projects_ProjectId", + column: x => x.ProjectId, + principalTable: "Projects", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ProjectTasks", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + PhaseId = table.Column(type: "uniqueidentifier", nullable: false), + CreationDate = table.Column(type: "datetime2", nullable: false), + Description = table.Column(type: "nvarchar(1000)", maxLength: 1000, nullable: true), + Name = table.Column(type: "nvarchar(200)", maxLength: 200, nullable: false), + Status = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ProjectTasks", x => x.Id); + table.ForeignKey( + name: "FK_ProjectTasks_ProjectPhases_PhaseId", + column: x => x.PhaseId, + principalTable: "ProjectPhases", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_TaskSections_ProjectTaskId", + table: "TaskSections", + column: "ProjectTaskId"); + + migrationBuilder.CreateIndex( + name: "IX_ProjectPhases_ProjectId", + table: "ProjectPhases", + column: "ProjectId"); + + migrationBuilder.CreateIndex( + name: "IX_ProjectTasks_PhaseId", + table: "ProjectTasks", + column: "PhaseId"); + + migrationBuilder.AddForeignKey( + name: "FK_AdditionalTimes_TaskSections_TaskSectionId", + table: "AdditionalTimes", + column: "TaskSectionId", + principalTable: "TaskSections", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_TaskSections_ProjectTasks_ProjectTaskId", + table: "TaskSections", + column: "ProjectTaskId", + principalTable: "ProjectTasks", + principalColumn: "Id"); + } + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251123123226_RoleInit.Designer.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251123123226_RoleInit.Designer.cs new file mode 100644 index 00000000..2ac5aede --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251123123226_RoleInit.Designer.cs @@ -0,0 +1,372 @@ +// +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("20251123123226_RoleInit")] + partial class RoleInit + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.22") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.CustomerAgg.Customer", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("Customers", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AllocatedTime") + .HasColumnType("time"); + + b.Property("AssignedUserId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("HasAssignmentOverride") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("HasTimeOverride") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("Level") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ParentId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("Level"); + + b.HasIndex("ParentId"); + + b.HasIndex("Level", "AssignedUserId"); + + b.ToTable("ProjectNodes", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AllocatedTime") + .HasColumnType("time"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("CurrentAssignedUserId") + .HasColumnType("bigint"); + + b.Property("InitialEstimatedHours") + .HasColumnType("time"); + + b.Property("SectionType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("TaskNodeId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("TaskNodeId"); + + b.ToTable("TaskSections", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSectionActivity", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("EndNotes") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("Notes") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("SectionId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("SectionId"); + + b.ToTable("TaskSectionActivities", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSectionAdditionalTime", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AddedAt") + .HasColumnType("datetime2"); + + b.Property("AddedByUserId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Hours") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("ProjectSectionId") + .HasColumnType("uniqueidentifier"); + + b.Property("Reason") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.HasKey("Id"); + + b.HasIndex("ProjectSectionId"); + + b.ToTable("AdditionalTimes", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.RoleAgg.Entities.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("RoleName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.HasKey("Id"); + + b.ToTable("Roles", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .HasMaxLength(150) + .HasColumnType("nvarchar(150)"); + + b.Property("FullName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("Mobile") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.Property("Password") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("ProfilePhotoPath") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("VerifyCode") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.HasKey("Id"); + + b.ToTable("Users", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", "Parent") + .WithMany("Children") + .HasForeignKey("ParentId") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("Parent"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", "TaskNode") + .WithMany("Sections") + .HasForeignKey("TaskNodeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("TaskNode"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSectionActivity", 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.ProjectSectionAdditionalTime", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", null) + .WithMany("AdditionalTimes") + .HasForeignKey("ProjectSectionId"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.RoleAgg.Entities.Role", b => + { + b.OwnsMany("GozareshgirProgramManager.Domain.PermissionAgg.Entities.Permission", "Permissions", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("Code") + .HasColumnType("int"); + + b1.Property("RoleId") + .HasColumnType("bigint"); + + b1.HasKey("Id"); + + b1.HasIndex("RoleId"); + + b1.ToTable("RolePermissions", (string)null); + + b1.WithOwner("Role") + .HasForeignKey("RoleId"); + + b1.Navigation("Role"); + }); + + b.Navigation("Permissions"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", b => + { + b.Navigation("Children"); + + b.Navigation("Sections"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.Navigation("Activities"); + + b.Navigation("AdditionalTimes"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251123123226_RoleInit.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251123123226_RoleInit.cs new file mode 100644 index 00000000..bea52da9 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251123123226_RoleInit.cs @@ -0,0 +1,64 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace GozareshgirProgramManager.Infrastructure.Migrations +{ + /// + public partial class RoleInit : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Roles", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + RoleName = table.Column(type: "nvarchar(100)", maxLength: 100, nullable: false), + CreationDate = table.Column(type: "datetime2", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Roles", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "RolePermissions", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Code = table.Column(type: "int", nullable: false), + RoleId = table.Column(type: "bigint", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_RolePermissions", x => x.Id); + table.ForeignKey( + name: "FK_RolePermissions_Roles_RoleId", + column: x => x.RoleId, + principalTable: "Roles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_RolePermissions_RoleId", + table: "RolePermissions", + column: "RoleId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "RolePermissions"); + + migrationBuilder.DropTable( + name: "Roles"); + } + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251123135308_RoleUpdate.Designer.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251123135308_RoleUpdate.Designer.cs new file mode 100644 index 00000000..f8e22836 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251123135308_RoleUpdate.Designer.cs @@ -0,0 +1,375 @@ +// +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("20251123135308_RoleUpdate")] + partial class RoleUpdate + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.22") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.CustomerAgg.Customer", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("Customers", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AllocatedTime") + .HasColumnType("time"); + + b.Property("AssignedUserId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("HasAssignmentOverride") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("HasTimeOverride") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("Level") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ParentId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("Level"); + + b.HasIndex("ParentId"); + + b.HasIndex("Level", "AssignedUserId"); + + b.ToTable("ProjectNodes", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AllocatedTime") + .HasColumnType("time"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("CurrentAssignedUserId") + .HasColumnType("bigint"); + + b.Property("InitialEstimatedHours") + .HasColumnType("time"); + + b.Property("SectionType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("TaskNodeId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("TaskNodeId"); + + b.ToTable("TaskSections", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSectionActivity", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("EndNotes") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("Notes") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("SectionId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("SectionId"); + + b.ToTable("TaskSectionActivities", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSectionAdditionalTime", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AddedAt") + .HasColumnType("datetime2"); + + b.Property("AddedByUserId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Hours") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("ProjectSectionId") + .HasColumnType("uniqueidentifier"); + + b.Property("Reason") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.HasKey("Id"); + + b.HasIndex("ProjectSectionId"); + + b.ToTable("AdditionalTimes", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.RoleAgg.Entities.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("GozareshgirRoleId") + .HasColumnType("bigint"); + + b.Property("RoleName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.HasKey("Id"); + + b.ToTable("Roles", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .HasMaxLength(150) + .HasColumnType("nvarchar(150)"); + + b.Property("FullName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("Mobile") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.Property("Password") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("ProfilePhotoPath") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("VerifyCode") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.HasKey("Id"); + + b.ToTable("Users", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", "Parent") + .WithMany("Children") + .HasForeignKey("ParentId") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("Parent"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", "TaskNode") + .WithMany("Sections") + .HasForeignKey("TaskNodeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("TaskNode"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSectionActivity", 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.ProjectSectionAdditionalTime", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", null) + .WithMany("AdditionalTimes") + .HasForeignKey("ProjectSectionId"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.RoleAgg.Entities.Role", b => + { + b.OwnsMany("GozareshgirProgramManager.Domain.PermissionAgg.Entities.Permission", "Permissions", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("Code") + .HasColumnType("int"); + + b1.Property("RoleId") + .HasColumnType("bigint"); + + b1.HasKey("Id"); + + b1.HasIndex("RoleId"); + + b1.ToTable("RolePermissions", (string)null); + + b1.WithOwner("Role") + .HasForeignKey("RoleId"); + + b1.Navigation("Role"); + }); + + b.Navigation("Permissions"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", b => + { + b.Navigation("Children"); + + b.Navigation("Sections"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.Navigation("Activities"); + + b.Navigation("AdditionalTimes"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251123135308_RoleUpdate.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251123135308_RoleUpdate.cs new file mode 100644 index 00000000..16b9be9c --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251123135308_RoleUpdate.cs @@ -0,0 +1,28 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace GozareshgirProgramManager.Infrastructure.Migrations +{ + /// + public partial class RoleUpdate : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "GozareshgirRoleId", + table: "Roles", + type: "bigint", + nullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "GozareshgirRoleId", + table: "Roles"); + } + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251125111142_add skills to entity.Designer.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251125111142_add skills to entity.Designer.cs new file mode 100644 index 00000000..827e389f --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251125111142_add skills to entity.Designer.cs @@ -0,0 +1,346 @@ +// +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("20251125111142_add skills to entity")] + partial class addskillstoentity + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.22") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.CustomerAgg.Customer", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("Customers", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AllocatedTime") + .HasColumnType("time"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("HasAssignmentOverride") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("HasTimeOverride") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("Level") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ParentId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("Level"); + + b.HasIndex("ParentId"); + + b.ToTable("ProjectNodes", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AllocatedTime") + .HasColumnType("time"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("CurrentAssignedUserId") + .HasColumnType("bigint"); + + b.Property("InitialEstimatedHours") + .HasColumnType("time"); + + b.Property("SkillId") + .HasColumnType("uniqueidentifier"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("TaskNodeId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("SkillId"); + + b.HasIndex("TaskNodeId"); + + b.ToTable("ProjectSections", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSectionActivity", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("EndNotes") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("Notes") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("SectionId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("SectionId"); + + b.ToTable("TaskSectionActivities", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSectionAdditionalTime", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AddedAt") + .HasColumnType("datetime2"); + + b.Property("AddedByUserId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Hours") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("ProjectSectionId") + .HasColumnType("uniqueidentifier"); + + b.Property("Reason") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.HasKey("Id"); + + b.HasIndex("ProjectSectionId"); + + b.ToTable("AdditionalTimes", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("Skills", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .HasMaxLength(150) + .HasColumnType("nvarchar(150)"); + + b.Property("FullName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("Mobile") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.Property("Password") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("ProfilePhotoPath") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("VerifyCode") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.HasKey("Id"); + + b.ToTable("Users", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", "Parent") + .WithMany("Children") + .HasForeignKey("ParentId") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("Parent"); + }); + + 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.ProjectNode", "TaskNode") + .WithMany("Sections") + .HasForeignKey("TaskNodeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Skill"); + + b.Navigation("TaskNode"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSectionActivity", 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.ProjectSectionAdditionalTime", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", null) + .WithMany("AdditionalTimes") + .HasForeignKey("ProjectSectionId"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", b => + { + b.Navigation("Children"); + + 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"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251125111142_add skills to entity.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251125111142_add skills to entity.cs new file mode 100644 index 00000000..944ad923 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251125111142_add skills to entity.cs @@ -0,0 +1,222 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace GozareshgirProgramManager.Infrastructure.Migrations +{ + /// + public partial class addskillstoentity : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_AdditionalTimes_TaskSections_ProjectSectionId", + table: "AdditionalTimes"); + + migrationBuilder.DropForeignKey( + name: "FK_TaskSectionActivities_TaskSections_SectionId", + table: "TaskSectionActivities"); + + migrationBuilder.DropForeignKey( + name: "FK_TaskSections_ProjectNodes_TaskNodeId", + table: "TaskSections"); + + migrationBuilder.DropIndex( + name: "IX_ProjectNodes_Level_AssignedUserId", + table: "ProjectNodes"); + + migrationBuilder.DropPrimaryKey( + name: "PK_TaskSections", + table: "TaskSections"); + + migrationBuilder.DropColumn( + name: "AssignedUserId", + table: "ProjectNodes"); + + migrationBuilder.DropColumn( + name: "SectionType", + table: "TaskSections"); + + migrationBuilder.RenameTable( + name: "TaskSections", + newName: "ProjectSections"); + + migrationBuilder.RenameIndex( + name: "IX_TaskSections_TaskNodeId", + table: "ProjectSections", + newName: "IX_ProjectSections_TaskNodeId"); + + migrationBuilder.AlterColumn( + name: "CurrentAssignedUserId", + table: "ProjectSections", + type: "bigint", + nullable: false, + defaultValue: 0L, + oldClrType: typeof(long), + oldType: "bigint", + oldNullable: true); + + migrationBuilder.AddColumn( + name: "SkillId", + table: "ProjectSections", + type: "uniqueidentifier", + nullable: false, + defaultValue: new Guid("00000000-0000-0000-0000-000000000000")); + + migrationBuilder.AddPrimaryKey( + name: "PK_ProjectSections", + table: "ProjectSections", + column: "Id"); + + migrationBuilder.CreateTable( + name: "Skills", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + Name = table.Column(type: "nvarchar(200)", maxLength: 200, nullable: false), + CreationDate = table.Column(type: "datetime2", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Skills", x => x.Id); + }); + + migrationBuilder.CreateIndex( + name: "IX_ProjectSections_SkillId", + table: "ProjectSections", + column: "SkillId"); + + migrationBuilder.AddForeignKey( + name: "FK_AdditionalTimes_ProjectSections_ProjectSectionId", + table: "AdditionalTimes", + column: "ProjectSectionId", + principalTable: "ProjectSections", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_ProjectSections_ProjectNodes_TaskNodeId", + table: "ProjectSections", + column: "TaskNodeId", + principalTable: "ProjectNodes", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_ProjectSections_Skills_SkillId", + table: "ProjectSections", + column: "SkillId", + principalTable: "Skills", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_TaskSectionActivities_ProjectSections_SectionId", + table: "TaskSectionActivities", + column: "SectionId", + principalTable: "ProjectSections", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_AdditionalTimes_ProjectSections_ProjectSectionId", + table: "AdditionalTimes"); + + migrationBuilder.DropForeignKey( + name: "FK_ProjectSections_ProjectNodes_TaskNodeId", + table: "ProjectSections"); + + migrationBuilder.DropForeignKey( + name: "FK_ProjectSections_Skills_SkillId", + table: "ProjectSections"); + + migrationBuilder.DropForeignKey( + name: "FK_TaskSectionActivities_ProjectSections_SectionId", + table: "TaskSectionActivities"); + + migrationBuilder.DropTable( + name: "Skills"); + + migrationBuilder.DropPrimaryKey( + name: "PK_ProjectSections", + table: "ProjectSections"); + + migrationBuilder.DropIndex( + name: "IX_ProjectSections_SkillId", + table: "ProjectSections"); + + migrationBuilder.DropColumn( + name: "SkillId", + table: "ProjectSections"); + + migrationBuilder.RenameTable( + name: "ProjectSections", + newName: "TaskSections"); + + migrationBuilder.RenameIndex( + name: "IX_ProjectSections_TaskNodeId", + table: "TaskSections", + newName: "IX_TaskSections_TaskNodeId"); + + migrationBuilder.AddColumn( + name: "AssignedUserId", + table: "ProjectNodes", + type: "bigint", + nullable: true); + + migrationBuilder.AlterColumn( + name: "CurrentAssignedUserId", + table: "TaskSections", + type: "bigint", + nullable: true, + oldClrType: typeof(long), + oldType: "bigint"); + + migrationBuilder.AddColumn( + name: "SectionType", + table: "TaskSections", + type: "nvarchar(50)", + maxLength: 50, + nullable: false, + defaultValue: ""); + + migrationBuilder.AddPrimaryKey( + name: "PK_TaskSections", + table: "TaskSections", + column: "Id"); + + migrationBuilder.CreateIndex( + name: "IX_ProjectNodes_Level_AssignedUserId", + table: "ProjectNodes", + columns: new[] { "Level", "AssignedUserId" }); + + migrationBuilder.AddForeignKey( + name: "FK_AdditionalTimes_TaskSections_ProjectSectionId", + table: "AdditionalTimes", + column: "ProjectSectionId", + principalTable: "TaskSections", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_TaskSectionActivities_TaskSections_SectionId", + table: "TaskSectionActivities", + column: "SectionId", + principalTable: "TaskSections", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_TaskSections_ProjectNodes_TaskNodeId", + table: "TaskSections", + column: "TaskNodeId", + principalTable: "ProjectNodes", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251125112542_change section key name.Designer.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251125112542_change section key name.Designer.cs new file mode 100644 index 00000000..9f6ea58c --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251125112542_change section key name.Designer.cs @@ -0,0 +1,346 @@ +// +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("20251125112542_change section key name")] + partial class changesectionkeyname + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.22") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.CustomerAgg.Customer", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("Customers", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AllocatedTime") + .HasColumnType("time"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("HasAssignmentOverride") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("HasTimeOverride") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("Level") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ParentId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("Level"); + + b.HasIndex("ParentId"); + + b.ToTable("ProjectNodes", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AllocatedTime") + .HasColumnType("time"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("CurrentAssignedUserId") + .HasColumnType("bigint"); + + b.Property("InitialEstimatedHours") + .HasColumnType("time"); + + b.Property("ProjectNodeId") + .HasColumnType("uniqueidentifier"); + + b.Property("SkillId") + .HasColumnType("uniqueidentifier"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.HasIndex("ProjectNodeId"); + + b.HasIndex("SkillId"); + + b.ToTable("ProjectSections", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSectionActivity", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("EndNotes") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("Notes") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("SectionId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("SectionId"); + + b.ToTable("TaskSectionActivities", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSectionAdditionalTime", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AddedAt") + .HasColumnType("datetime2"); + + b.Property("AddedByUserId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Hours") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("ProjectSectionId") + .HasColumnType("uniqueidentifier"); + + b.Property("Reason") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.HasKey("Id"); + + b.HasIndex("ProjectSectionId"); + + b.ToTable("AdditionalTimes", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("Skills", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .HasMaxLength(150) + .HasColumnType("nvarchar(150)"); + + b.Property("FullName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("Mobile") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.Property("Password") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("ProfilePhotoPath") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("VerifyCode") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.HasKey("Id"); + + b.ToTable("Users", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", "Parent") + .WithMany("Children") + .HasForeignKey("ParentId") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("Parent"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", "ProjectNode") + .WithMany("Sections") + .HasForeignKey("ProjectNodeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", "Skill") + .WithMany("Sections") + .HasForeignKey("SkillId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ProjectNode"); + + b.Navigation("Skill"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSectionActivity", 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.ProjectSectionAdditionalTime", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", null) + .WithMany("AdditionalTimes") + .HasForeignKey("ProjectSectionId"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", b => + { + b.Navigation("Children"); + + 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"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251125112542_change section key name.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251125112542_change section key name.cs new file mode 100644 index 00000000..8fd3deda --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251125112542_change section key name.cs @@ -0,0 +1,62 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace GozareshgirProgramManager.Infrastructure.Migrations +{ + /// + public partial class changesectionkeyname : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_ProjectSections_ProjectNodes_TaskNodeId", + table: "ProjectSections"); + + migrationBuilder.RenameColumn( + name: "TaskNodeId", + table: "ProjectSections", + newName: "ProjectNodeId"); + + migrationBuilder.RenameIndex( + name: "IX_ProjectSections_TaskNodeId", + table: "ProjectSections", + newName: "IX_ProjectSections_ProjectNodeId"); + + migrationBuilder.AddForeignKey( + name: "FK_ProjectSections_ProjectNodes_ProjectNodeId", + table: "ProjectSections", + column: "ProjectNodeId", + principalTable: "ProjectNodes", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_ProjectSections_ProjectNodes_ProjectNodeId", + table: "ProjectSections"); + + migrationBuilder.RenameColumn( + name: "ProjectNodeId", + table: "ProjectSections", + newName: "TaskNodeId"); + + migrationBuilder.RenameIndex( + name: "IX_ProjectSections_ProjectNodeId", + table: "ProjectSections", + newName: "IX_ProjectSections_TaskNodeId"); + + migrationBuilder.AddForeignKey( + name: "FK_ProjectSections_ProjectNodes_TaskNodeId", + table: "ProjectSections", + column: "TaskNodeId", + principalTable: "ProjectNodes", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251125145830_change project node on delete to cascade.Designer.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251125145830_change project node on delete to cascade.Designer.cs new file mode 100644 index 00000000..c8e06582 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251125145830_change project node on delete to cascade.Designer.cs @@ -0,0 +1,346 @@ +// +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("20251125145830_change project node on delete to cascade")] + partial class changeprojectnodeondeletetocascade + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.22") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.CustomerAgg.Customer", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("Customers", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AllocatedTime") + .HasColumnType("time"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("HasAssignmentOverride") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("HasTimeOverride") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("Level") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ParentId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("Level"); + + b.HasIndex("ParentId"); + + b.ToTable("ProjectNodes", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AllocatedTime") + .HasColumnType("time"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("CurrentAssignedUserId") + .HasColumnType("bigint"); + + b.Property("InitialEstimatedHours") + .HasColumnType("time"); + + b.Property("ProjectNodeId") + .HasColumnType("uniqueidentifier"); + + b.Property("SkillId") + .HasColumnType("uniqueidentifier"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.HasIndex("ProjectNodeId"); + + b.HasIndex("SkillId"); + + b.ToTable("ProjectSections", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSectionActivity", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("EndNotes") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("Notes") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("SectionId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("SectionId"); + + b.ToTable("TaskSectionActivities", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSectionAdditionalTime", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AddedAt") + .HasColumnType("datetime2"); + + b.Property("AddedByUserId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Hours") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("ProjectSectionId") + .HasColumnType("uniqueidentifier"); + + b.Property("Reason") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.HasKey("Id"); + + b.HasIndex("ProjectSectionId"); + + b.ToTable("AdditionalTimes", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("Skills", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .HasMaxLength(150) + .HasColumnType("nvarchar(150)"); + + b.Property("FullName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("Mobile") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.Property("Password") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("ProfilePhotoPath") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("VerifyCode") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.HasKey("Id"); + + b.ToTable("Users", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", "Parent") + .WithMany("Children") + .HasForeignKey("ParentId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("Parent"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", "ProjectNode") + .WithMany("Sections") + .HasForeignKey("ProjectNodeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", "Skill") + .WithMany("Sections") + .HasForeignKey("SkillId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ProjectNode"); + + b.Navigation("Skill"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSectionActivity", 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.ProjectSectionAdditionalTime", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", null) + .WithMany("AdditionalTimes") + .HasForeignKey("ProjectSectionId"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", b => + { + b.Navigation("Children"); + + 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"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251125145830_change project node on delete to cascade.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251125145830_change project node on delete to cascade.cs new file mode 100644 index 00000000..c2d73e3d --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251125145830_change project node on delete to cascade.cs @@ -0,0 +1,22 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace GozareshgirProgramManager.Infrastructure.Migrations +{ + /// + public partial class changeprojectnodeondeletetocascade : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + + } + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251125164239_change section and additionalTime description.Designer.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251125164239_change section and additionalTime description.Designer.cs new file mode 100644 index 00000000..c35702a7 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251125164239_change section and additionalTime description.Designer.cs @@ -0,0 +1,349 @@ +// +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("20251125164239_change section and additionalTime description")] + partial class changesectionandadditionalTimedescription + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.22") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.CustomerAgg.Customer", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("Customers", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AllocatedTime") + .HasColumnType("time"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("HasAssignmentOverride") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("HasTimeOverride") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("Level") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ParentId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("Level"); + + b.HasIndex("ParentId"); + + b.ToTable("ProjectNodes", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("CurrentAssignedUserId") + .HasColumnType("bigint"); + + b.Property("InitialDescription") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("InitialEstimatedHours") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("ProjectNodeId") + .HasColumnType("uniqueidentifier"); + + b.Property("SkillId") + .HasColumnType("uniqueidentifier"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.HasIndex("ProjectNodeId"); + + b.HasIndex("SkillId"); + + b.ToTable("ProjectSections", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSectionActivity", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("EndNotes") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("Notes") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("SectionId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("SectionId"); + + b.ToTable("ProjectSectionActivities", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSectionAdditionalTime", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AddedAt") + .HasColumnType("datetime2"); + + b.Property("AddedByUserId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Hours") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("ProjectSectionId") + .HasColumnType("uniqueidentifier"); + + b.Property("Reason") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.HasKey("Id"); + + b.HasIndex("ProjectSectionId"); + + b.ToTable("AdditionalTimes", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("Skills", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .HasMaxLength(150) + .HasColumnType("nvarchar(150)"); + + b.Property("FullName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("Mobile") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.Property("Password") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("ProfilePhotoPath") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("VerifyCode") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.HasKey("Id"); + + b.ToTable("Users", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", "Parent") + .WithMany("Children") + .HasForeignKey("ParentId") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("Parent"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", "ProjectNode") + .WithMany("Sections") + .HasForeignKey("ProjectNodeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", "Skill") + .WithMany("Sections") + .HasForeignKey("SkillId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ProjectNode"); + + b.Navigation("Skill"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSectionActivity", 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.ProjectSectionAdditionalTime", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", null) + .WithMany("AdditionalTimes") + .HasForeignKey("ProjectSectionId"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", b => + { + b.Navigation("Children"); + + 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"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251125164239_change section and additionalTime description.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251125164239_change section and additionalTime description.cs new file mode 100644 index 00000000..6c2696bc --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251125164239_change section and additionalTime description.cs @@ -0,0 +1,142 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace GozareshgirProgramManager.Infrastructure.Migrations +{ + /// + public partial class changesectionandadditionalTimedescription : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_ProjectNodes_ProjectNodes_ParentId", + table: "ProjectNodes"); + + migrationBuilder.DropForeignKey( + name: "FK_TaskSectionActivities_ProjectSections_SectionId", + table: "TaskSectionActivities"); + + migrationBuilder.DropPrimaryKey( + name: "PK_TaskSectionActivities", + table: "TaskSectionActivities"); + + migrationBuilder.DropColumn( + name: "AllocatedTime", + table: "ProjectSections"); + + migrationBuilder.RenameTable( + name: "TaskSectionActivities", + newName: "ProjectSectionActivities"); + + migrationBuilder.RenameIndex( + name: "IX_TaskSectionActivities_SectionId", + table: "ProjectSectionActivities", + newName: "IX_ProjectSectionActivities_SectionId"); + + migrationBuilder.AlterColumn( + name: "InitialEstimatedHours", + table: "ProjectSections", + type: "nvarchar(30)", + maxLength: 30, + nullable: false, + oldClrType: typeof(TimeSpan), + oldType: "time"); + + migrationBuilder.AddColumn( + name: "InitialDescription", + table: "ProjectSections", + type: "nvarchar(500)", + maxLength: 500, + nullable: true); + + migrationBuilder.AddPrimaryKey( + name: "PK_ProjectSectionActivities", + table: "ProjectSectionActivities", + column: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_ProjectNodes_ProjectNodes_ParentId", + table: "ProjectNodes", + column: "ParentId", + principalTable: "ProjectNodes", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + + migrationBuilder.AddForeignKey( + name: "FK_ProjectSectionActivities_ProjectSections_SectionId", + table: "ProjectSectionActivities", + column: "SectionId", + principalTable: "ProjectSections", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_ProjectNodes_ProjectNodes_ParentId", + table: "ProjectNodes"); + + migrationBuilder.DropForeignKey( + name: "FK_ProjectSectionActivities_ProjectSections_SectionId", + table: "ProjectSectionActivities"); + + migrationBuilder.DropPrimaryKey( + name: "PK_ProjectSectionActivities", + table: "ProjectSectionActivities"); + + migrationBuilder.DropColumn( + name: "InitialDescription", + table: "ProjectSections"); + + migrationBuilder.RenameTable( + name: "ProjectSectionActivities", + newName: "TaskSectionActivities"); + + migrationBuilder.RenameIndex( + name: "IX_ProjectSectionActivities_SectionId", + table: "TaskSectionActivities", + newName: "IX_TaskSectionActivities_SectionId"); + + migrationBuilder.AlterColumn( + name: "InitialEstimatedHours", + table: "ProjectSections", + type: "time", + nullable: false, + oldClrType: typeof(string), + oldType: "nvarchar(30)", + oldMaxLength: 30); + + migrationBuilder.AddColumn( + name: "AllocatedTime", + table: "ProjectSections", + type: "time", + nullable: true); + + migrationBuilder.AddPrimaryKey( + name: "PK_TaskSectionActivities", + table: "TaskSectionActivities", + column: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_ProjectNodes_ProjectNodes_ParentId", + table: "ProjectNodes", + column: "ParentId", + principalTable: "ProjectNodes", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_TaskSectionActivities_ProjectSections_SectionId", + table: "TaskSectionActivities", + column: "SectionId", + principalTable: "ProjectSections", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251126122836_AddUserRoleTable.Designer.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251126122836_AddUserRoleTable.Designer.cs new file mode 100644 index 00000000..1132e866 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251126122836_AddUserRoleTable.Designer.cs @@ -0,0 +1,406 @@ +// +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("20251126122836_AddUserRoleTable")] + partial class AddUserRoleTable + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.22") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.CustomerAgg.Customer", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("Customers", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AllocatedTime") + .HasColumnType("time"); + + b.Property("AssignedUserId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("HasAssignmentOverride") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("HasTimeOverride") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("Level") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ParentId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("Level"); + + b.HasIndex("ParentId"); + + b.HasIndex("Level", "AssignedUserId"); + + b.ToTable("ProjectNodes", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AllocatedTime") + .HasColumnType("time"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("CurrentAssignedUserId") + .HasColumnType("bigint"); + + b.Property("InitialEstimatedHours") + .HasColumnType("time"); + + b.Property("SectionType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("TaskNodeId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("TaskNodeId"); + + b.ToTable("TaskSections", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSectionActivity", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("EndNotes") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("Notes") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("SectionId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("SectionId"); + + b.ToTable("TaskSectionActivities", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSectionAdditionalTime", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AddedAt") + .HasColumnType("datetime2"); + + b.Property("AddedByUserId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Hours") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("ProjectSectionId") + .HasColumnType("uniqueidentifier"); + + b.Property("Reason") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.HasKey("Id"); + + b.HasIndex("ProjectSectionId"); + + b.ToTable("AdditionalTimes", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.RoleAgg.Entities.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("GozareshgirRoleId") + .HasColumnType("bigint"); + + b.Property("RoleName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.HasKey("Id"); + + b.ToTable("Roles", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .HasMaxLength(150) + .HasColumnType("nvarchar(150)"); + + b.Property("FullName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("Mobile") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.Property("Password") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("ProfilePhotoPath") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("VerifyCode") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.HasKey("Id"); + + b.ToTable("Users", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", "Parent") + .WithMany("Children") + .HasForeignKey("ParentId") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("Parent"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", "TaskNode") + .WithMany("Sections") + .HasForeignKey("TaskNodeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("TaskNode"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSectionActivity", 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.ProjectSectionAdditionalTime", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", null) + .WithMany("AdditionalTimes") + .HasForeignKey("ProjectSectionId"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.RoleAgg.Entities.Role", b => + { + b.OwnsMany("GozareshgirProgramManager.Domain.PermissionAgg.Entities.Permission", "Permissions", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("Code") + .HasColumnType("int"); + + b1.Property("RoleId") + .HasColumnType("bigint"); + + b1.HasKey("Id"); + + b1.HasIndex("RoleId"); + + b1.ToTable("RolePermissions", (string)null); + + b1.WithOwner("Role") + .HasForeignKey("RoleId"); + + b1.Navigation("Role"); + }); + + b.Navigation("Permissions"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b => + { + b.OwnsMany("GozareshgirProgramManager.Domain.RoleUserAgg.RoleUser", "RoleUser", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("RoleId") + .HasColumnType("bigint"); + + b1.Property("UserId") + .HasColumnType("bigint"); + + b1.HasKey("Id"); + + b1.HasIndex("UserId"); + + b1.ToTable("RoleUsers", (string)null); + + b1.WithOwner("User") + .HasForeignKey("UserId"); + + b1.Navigation("User"); + }); + + b.Navigation("RoleUser"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", b => + { + b.Navigation("Children"); + + b.Navigation("Sections"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.Navigation("Activities"); + + b.Navigation("AdditionalTimes"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251126122836_AddUserRoleTable.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251126122836_AddUserRoleTable.cs new file mode 100644 index 00000000..23d03281 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251126122836_AddUserRoleTable.cs @@ -0,0 +1,46 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace GozareshgirProgramManager.Infrastructure.Migrations +{ + /// + public partial class AddUserRoleTable : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "RoleUsers", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + RoleId = table.Column(type: "bigint", nullable: false), + UserId = table.Column(type: "bigint", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_RoleUsers", x => x.Id); + table.ForeignKey( + name: "FK_RoleUsers_Users_UserId", + column: x => x.UserId, + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_RoleUsers_UserId", + table: "RoleUsers", + column: "UserId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "RoleUsers"); + } + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251201120420_change projects from nodes to three seprated pieces.Designer.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251201120420_change projects from nodes to three seprated pieces.Designer.cs new file mode 100644 index 00000000..a865122a --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251201120420_change projects from nodes to three seprated pieces.Designer.cs @@ -0,0 +1,556 @@ +// +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("20251201120420_change projects from nodes to three seprated pieces")] + partial class changeprojectsfromnodestothreesepratedpieces + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.CustomerAgg.Customer", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("Customers", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("HasAssignmentOverride") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("PlannedEndDate") + .HasColumnType("datetime2"); + + b.Property("PlannedStartDate") + .HasColumnType("datetime2"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.ToTable("Projects", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("HasAssignmentOverride") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("OrderIndex") + .HasColumnType("int"); + + b.Property("ProjectId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.ToTable("ProjectPhases", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("CurrentAssignedUserId") + .HasColumnType("bigint"); + + b.Property("InitialDescription") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("InitialEstimatedHours") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("SkillId") + .HasColumnType("uniqueidentifier"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("TaskId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("SkillId"); + + b.HasIndex("TaskId"); + + b.ToTable("ProjectSections", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSectionActivity", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("EndNotes") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("Notes") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("SectionId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("SectionId"); + + b.ToTable("ProjectSectionActivities", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSectionAdditionalTime", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AddedAt") + .HasColumnType("datetime2"); + + b.Property("AddedByUserId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Hours") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("ProjectSectionId") + .HasColumnType("uniqueidentifier"); + + b.Property("Reason") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.HasKey("Id"); + + b.HasIndex("ProjectSectionId"); + + b.ToTable("ProjectSectionAdditionalTimes", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AllocatedTime") + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("DueDate") + .HasColumnType("datetime2"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("HasAssignmentOverride") + .HasColumnType("bit"); + + b.Property("HasTimeOverride") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("OrderIndex") + .HasColumnType("int"); + + b.Property("PhaseId") + .HasColumnType("uniqueidentifier"); + + b.Property("Priority") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.HasIndex("PhaseId"); + + b.ToTable("ProjectTasks", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.RoleAgg.Entities.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("GozareshgirRoleId") + .HasColumnType("bigint"); + + b.Property("RoleName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.HasKey("Id"); + + b.ToTable("Roles", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("Skills", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .HasMaxLength(150) + .HasColumnType("nvarchar(150)"); + + b.Property("FullName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("Mobile") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.Property("Password") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("ProfilePhotoPath") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("VerifyCode") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.HasKey("Id"); + + b.ToTable("Users", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.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.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.ProjectSectionActivity", 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.ProjectSectionAdditionalTime", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", null) + .WithMany("AdditionalTimes") + .HasForeignKey("ProjectSectionId"); + }); + + 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.RoleAgg.Entities.Role", b => + { + b.OwnsMany("GozareshgirProgramManager.Domain.PermissionAgg.Entities.Permission", "Permissions", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("Code") + .HasColumnType("int"); + + b1.Property("RoleId") + .HasColumnType("bigint"); + + b1.HasKey("Id"); + + b1.HasIndex("RoleId"); + + b1.ToTable("RolePermissions", (string)null); + + b1.WithOwner("Role") + .HasForeignKey("RoleId"); + + b1.Navigation("Role"); + }); + + b.Navigation("Permissions"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b => + { + b.OwnsMany("GozareshgirProgramManager.Domain.RoleUserAgg.RoleUser", "RoleUser", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("RoleId") + .HasColumnType("bigint"); + + b1.Property("UserId") + .HasColumnType("bigint"); + + b1.HasKey("Id"); + + b1.HasIndex("UserId"); + + b1.ToTable("RoleUsers", (string)null); + + b1.WithOwner("User") + .HasForeignKey("UserId"); + + b1.Navigation("User"); + }); + + b.Navigation("RoleUser"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project", b => + { + b.Navigation("Phases"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", b => + { + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.Navigation("Activities"); + + b.Navigation("AdditionalTimes"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", b => + { + b.Navigation("Sections"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", b => + { + b.Navigation("Sections"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251201120420_change projects from nodes to three seprated pieces.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251201120420_change projects from nodes to three seprated pieces.cs new file mode 100644 index 00000000..b6e789f8 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251201120420_change projects from nodes to three seprated pieces.cs @@ -0,0 +1,287 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace GozareshgirProgramManager.Infrastructure.Migrations +{ + /// + public partial class changeprojectsfromnodestothreesepratedpieces : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_AdditionalTimes_ProjectSections_ProjectSectionId", + table: "AdditionalTimes"); + + migrationBuilder.DropForeignKey( + name: "FK_ProjectSections_ProjectNodes_ProjectNodeId", + table: "ProjectSections"); + + migrationBuilder.DropTable( + name: "ProjectNodes"); + + migrationBuilder.DropPrimaryKey( + name: "PK_AdditionalTimes", + table: "AdditionalTimes"); + + migrationBuilder.RenameTable( + name: "AdditionalTimes", + newName: "ProjectSectionAdditionalTimes"); + + migrationBuilder.RenameColumn( + name: "ProjectNodeId", + table: "ProjectSections", + newName: "TaskId"); + + migrationBuilder.RenameIndex( + name: "IX_ProjectSections_ProjectNodeId", + table: "ProjectSections", + newName: "IX_ProjectSections_TaskId"); + + migrationBuilder.RenameIndex( + name: "IX_AdditionalTimes_ProjectSectionId", + table: "ProjectSectionAdditionalTimes", + newName: "IX_ProjectSectionAdditionalTimes_ProjectSectionId"); + + migrationBuilder.AddColumn( + name: "IsActive", + table: "ProjectSectionActivities", + type: "bit", + nullable: false, + defaultValue: false); + + migrationBuilder.AlterColumn( + name: "Reason", + table: "ProjectSectionAdditionalTimes", + type: "nvarchar(500)", + maxLength: 500, + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(1000)", + oldMaxLength: 1000, + oldNullable: true); + + migrationBuilder.AddPrimaryKey( + name: "PK_ProjectSectionAdditionalTimes", + table: "ProjectSectionAdditionalTimes", + column: "Id"); + + migrationBuilder.CreateTable( + name: "Projects", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + StartDate = table.Column(type: "datetime2", nullable: true), + EndDate = table.Column(type: "datetime2", nullable: true), + PlannedStartDate = table.Column(type: "datetime2", nullable: true), + PlannedEndDate = table.Column(type: "datetime2", nullable: true), + Status = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: false), + CreationDate = table.Column(type: "datetime2", nullable: false), + Name = table.Column(type: "nvarchar(200)", maxLength: 200, nullable: false), + Description = table.Column(type: "nvarchar(1000)", maxLength: 1000, nullable: true), + HasAssignmentOverride = table.Column(type: "bit", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Projects", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "ProjectPhases", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + ProjectId = table.Column(type: "uniqueidentifier", nullable: false), + Status = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: false), + StartDate = table.Column(type: "datetime2", nullable: true), + EndDate = table.Column(type: "datetime2", nullable: true), + OrderIndex = table.Column(type: "int", nullable: false), + CreationDate = table.Column(type: "datetime2", nullable: false), + Name = table.Column(type: "nvarchar(200)", maxLength: 200, nullable: false), + Description = table.Column(type: "nvarchar(1000)", maxLength: 1000, nullable: true), + HasAssignmentOverride = table.Column(type: "bit", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ProjectPhases", x => x.Id); + table.ForeignKey( + name: "FK_ProjectPhases_Projects_ProjectId", + column: x => x.ProjectId, + principalTable: "Projects", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ProjectTasks", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + PhaseId = table.Column(type: "uniqueidentifier", nullable: false), + Status = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: false), + Priority = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: false), + StartDate = table.Column(type: "datetime2", nullable: true), + EndDate = table.Column(type: "datetime2", nullable: true), + DueDate = table.Column(type: "datetime2", nullable: true), + OrderIndex = table.Column(type: "int", nullable: false), + AllocatedTime = table.Column(type: "nvarchar(30)", maxLength: 30, nullable: true), + HasTimeOverride = table.Column(type: "bit", nullable: false), + HasAssignmentOverride = table.Column(type: "bit", nullable: false), + CreationDate = table.Column(type: "datetime2", nullable: false), + Name = table.Column(type: "nvarchar(200)", maxLength: 200, nullable: false), + Description = table.Column(type: "nvarchar(1000)", maxLength: 1000, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_ProjectTasks", x => x.Id); + table.ForeignKey( + name: "FK_ProjectTasks_ProjectPhases_PhaseId", + column: x => x.PhaseId, + principalTable: "ProjectPhases", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_ProjectPhases_ProjectId", + table: "ProjectPhases", + column: "ProjectId"); + + migrationBuilder.CreateIndex( + name: "IX_ProjectTasks_PhaseId", + table: "ProjectTasks", + column: "PhaseId"); + + migrationBuilder.AddForeignKey( + name: "FK_ProjectSectionAdditionalTimes_ProjectSections_ProjectSectionId", + table: "ProjectSectionAdditionalTimes", + column: "ProjectSectionId", + principalTable: "ProjectSections", + principalColumn: "Id"); + + // migrationBuilder.AddForeignKey( + // name: "FK_ProjectSections_ProjectTasks_TaskId", + // table: "ProjectSections", + // column: "TaskId", + // principalTable: "ProjectTasks", + // principalColumn: "Id", + // onDelete: ReferentialAction.Cascade); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_ProjectSectionAdditionalTimes_ProjectSections_ProjectSectionId", + table: "ProjectSectionAdditionalTimes"); + + // migrationBuilder.DropForeignKey( + // name: "FK_ProjectSections_ProjectTasks_TaskId", + // table: "ProjectSections"); + + migrationBuilder.DropTable( + name: "ProjectTasks"); + + migrationBuilder.DropTable( + name: "ProjectPhases"); + + migrationBuilder.DropTable( + name: "Projects"); + + migrationBuilder.DropPrimaryKey( + name: "PK_ProjectSectionAdditionalTimes", + table: "ProjectSectionAdditionalTimes"); + + migrationBuilder.DropColumn( + name: "IsActive", + table: "ProjectSectionActivities"); + + migrationBuilder.RenameTable( + name: "ProjectSectionAdditionalTimes", + newName: "AdditionalTimes"); + + migrationBuilder.RenameColumn( + name: "TaskId", + table: "ProjectSections", + newName: "ProjectNodeId"); + + migrationBuilder.RenameIndex( + name: "IX_ProjectSections_TaskId", + table: "ProjectSections", + newName: "IX_ProjectSections_ProjectNodeId"); + + migrationBuilder.RenameIndex( + name: "IX_ProjectSectionAdditionalTimes_ProjectSectionId", + table: "AdditionalTimes", + newName: "IX_AdditionalTimes_ProjectSectionId"); + + migrationBuilder.AlterColumn( + name: "Reason", + table: "AdditionalTimes", + type: "nvarchar(1000)", + maxLength: 1000, + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(500)", + oldMaxLength: 500, + oldNullable: true); + + migrationBuilder.AddPrimaryKey( + name: "PK_AdditionalTimes", + table: "AdditionalTimes", + column: "Id"); + + migrationBuilder.CreateTable( + name: "ProjectNodes", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + ParentId = table.Column(type: "uniqueidentifier", nullable: true), + AllocatedTime = table.Column(type: "time", nullable: true), + CreationDate = table.Column(type: "datetime2", nullable: false), + Description = table.Column(type: "nvarchar(1000)", maxLength: 1000, nullable: true), + HasAssignmentOverride = table.Column(type: "bit", nullable: false, defaultValue: false), + HasTimeOverride = table.Column(type: "bit", nullable: false, defaultValue: false), + Level = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: false), + Name = table.Column(type: "nvarchar(200)", maxLength: 200, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ProjectNodes", x => x.Id); + table.ForeignKey( + name: "FK_ProjectNodes_ProjectNodes_ParentId", + column: x => x.ParentId, + principalTable: "ProjectNodes", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateIndex( + name: "IX_ProjectNodes_Level", + table: "ProjectNodes", + column: "Level"); + + migrationBuilder.CreateIndex( + name: "IX_ProjectNodes_ParentId", + table: "ProjectNodes", + column: "ParentId"); + + migrationBuilder.AddForeignKey( + name: "FK_AdditionalTimes_ProjectSections_ProjectSectionId", + table: "AdditionalTimes", + column: "ProjectSectionId", + principalTable: "ProjectSections", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_ProjectSections_ProjectNodes_ProjectNodeId", + table: "ProjectSections", + column: "ProjectNodeId", + principalTable: "ProjectNodes", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251201150949_SalaryPaymentSettingInit.Designer.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251201150949_SalaryPaymentSettingInit.Designer.cs new file mode 100644 index 00000000..df7b277f --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251201150949_SalaryPaymentSettingInit.Designer.cs @@ -0,0 +1,524 @@ +// +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("20251201150949_SalaryPaymentSettingInit")] + partial class SalaryPaymentSettingInit + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.22") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.CustomerAgg.Customer", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("Customers", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AllocatedTime") + .HasColumnType("time"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("HasAssignmentOverride") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("HasTimeOverride") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("Level") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ParentId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("Level"); + + b.HasIndex("ParentId"); + + b.ToTable("ProjectNodes", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("CurrentAssignedUserId") + .HasColumnType("bigint"); + + b.Property("InitialDescription") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("InitialEstimatedHours") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("ProjectNodeId") + .HasColumnType("uniqueidentifier"); + + b.Property("SkillId") + .HasColumnType("uniqueidentifier"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.HasIndex("ProjectNodeId"); + + b.HasIndex("SkillId"); + + b.ToTable("ProjectSections", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSectionActivity", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("EndNotes") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("Notes") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("SectionId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("SectionId"); + + b.ToTable("ProjectSectionActivities", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSectionAdditionalTime", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AddedAt") + .HasColumnType("datetime2"); + + b.Property("AddedByUserId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Hours") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("ProjectSectionId") + .HasColumnType("uniqueidentifier"); + + b.Property("Reason") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.HasKey("Id"); + + b.HasIndex("ProjectSectionId"); + + b.ToTable("AdditionalTimes", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.RoleAgg.Entities.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("GozareshgirRoleId") + .HasColumnType("bigint"); + + b.Property("RoleName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.HasKey("Id"); + + b.ToTable("Roles", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities.SalaryPaymentSetting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("EndSettingDate") + .HasColumnType("datetime2"); + + b.Property("HolidayWorking") + .HasColumnType("bit"); + + b.Property("MonthlySalary") + .HasColumnType("float"); + + b.Property("StartSettingDate") + .HasColumnType("datetime2"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.ToTable("SalaryPaymentSetting", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("Skills", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .HasMaxLength(150) + .HasColumnType("nvarchar(150)"); + + b.Property("FullName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("Mobile") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.Property("Password") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("ProfilePhotoPath") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("VerifyCode") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.HasKey("Id"); + + b.ToTable("Users", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", "Parent") + .WithMany("Children") + .HasForeignKey("ParentId") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("Parent"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", "ProjectNode") + .WithMany("Sections") + .HasForeignKey("ProjectNodeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", "Skill") + .WithMany("Sections") + .HasForeignKey("SkillId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ProjectNode"); + + b.Navigation("Skill"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSectionActivity", 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.ProjectSectionAdditionalTime", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", null) + .WithMany("AdditionalTimes") + .HasForeignKey("ProjectSectionId"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.RoleAgg.Entities.Role", b => + { + b.OwnsMany("GozareshgirProgramManager.Domain.PermissionAgg.Entities.Permission", "Permissions", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("Code") + .HasColumnType("int"); + + b1.Property("RoleId") + .HasColumnType("bigint"); + + b1.HasKey("Id"); + + b1.HasIndex("RoleId"); + + b1.ToTable("RolePermissions", (string)null); + + b1.WithOwner("Role") + .HasForeignKey("RoleId"); + + b1.Navigation("Role"); + }); + + b.Navigation("Permissions"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities.SalaryPaymentSetting", b => + { + b.OwnsMany("GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities.WorkingHours", "WorkingHoursList", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("EndShiftOne") + .HasColumnType("time(0)"); + + b1.Property("EndShiftTwo") + .HasColumnType("time(0)"); + + b1.Property("HasRestTime") + .HasColumnType("bit"); + + b1.Property("HasShiftOne") + .HasColumnType("bit"); + + b1.Property("HasShiftTow") + .HasColumnType("bit"); + + b1.Property("PersianDayOfWeek") + .HasColumnType("int"); + + b1.Property("RestTime") + .HasColumnType("time(0)"); + + b1.Property("SalaryPaymentSettingId") + .HasColumnType("bigint"); + + b1.Property("ShiftDurationInMinutes") + .HasColumnType("int"); + + b1.Property("StartShiftOne") + .HasColumnType("time(0)"); + + b1.Property("StartShiftTwo") + .HasColumnType("time(0)"); + + b1.HasKey("Id"); + + b1.HasIndex("SalaryPaymentSettingId"); + + b1.ToTable("WorkingHours", (string)null); + + b1.WithOwner("SalaryPaymentSetting") + .HasForeignKey("SalaryPaymentSettingId"); + + b1.Navigation("SalaryPaymentSetting"); + }); + + b.Navigation("WorkingHoursList"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b => + { + b.OwnsMany("GozareshgirProgramManager.Domain.RoleUserAgg.RoleUser", "RoleUser", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("RoleId") + .HasColumnType("bigint"); + + b1.Property("UserId") + .HasColumnType("bigint"); + + b1.HasKey("Id"); + + b1.HasIndex("UserId"); + + b1.ToTable("RoleUsers", (string)null); + + b1.WithOwner("User") + .HasForeignKey("UserId"); + + b1.Navigation("User"); + }); + + b.Navigation("RoleUser"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectNode", b => + { + b.Navigation("Children"); + + 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"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251201150949_SalaryPaymentSettingInit.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251201150949_SalaryPaymentSettingInit.cs new file mode 100644 index 00000000..8ae61fbb --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251201150949_SalaryPaymentSettingInit.cs @@ -0,0 +1,87 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace GozareshgirProgramManager.Infrastructure.Migrations +{ + /// + public partial class SalaryPaymentSettingInit : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "SalaryPaymentSetting", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + HolidayWorking = table.Column(type: "bit", nullable: false), + UserId = table.Column(type: "bigint", nullable: false), + MonthlySalary = table.Column(type: "float", nullable: false), + StartSettingDate = table.Column(type: "datetime2", nullable: true), + EndSettingDate = table.Column(type: "datetime2", nullable: true), + CreationDate = table.Column(type: "datetime2", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_SalaryPaymentSetting", x => x.Id); + }); + + + + migrationBuilder.CreateTable( + name: "WorkingHours", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + StartShiftOne = table.Column(type: "time(0)", nullable: false), + EndShiftOne = table.Column(type: "time(0)", nullable: false), + StartShiftTwo = table.Column(type: "time(0)", nullable: false), + EndShiftTwo = table.Column(type: "time(0)", nullable: false), + RestTime = table.Column(type: "time(0)", nullable: false), + HasShiftOne = table.Column(type: "bit", nullable: false), + HasShiftTow = table.Column(type: "bit", nullable: false), + HasRestTime = table.Column(type: "bit", nullable: false), + ShiftDurationInMinutes = table.Column(type: "int", nullable: false), + PersianDayOfWeek = table.Column(type: "int", nullable: false), + SalaryPaymentSettingId = table.Column(type: "bigint", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_WorkingHours", x => x.Id); + table.ForeignKey( + name: "FK_WorkingHours_SalaryPaymentSetting_SalaryPaymentSettingId", + column: x => x.SalaryPaymentSettingId, + principalTable: "SalaryPaymentSetting", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + + + migrationBuilder.CreateIndex( + name: "IX_WorkingHours_SalaryPaymentSettingId", + table: "WorkingHours", + column: "SalaryPaymentSettingId"); + + + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + + + migrationBuilder.DropTable( + name: "WorkingHours"); + + migrationBuilder.DropTable( + name: "SalaryPaymentSetting"); + + + } + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251202113519_IsActiveDayToWorkingHours.Designer.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251202113519_IsActiveDayToWorkingHours.Designer.cs new file mode 100644 index 00000000..f6ad2cf2 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251202113519_IsActiveDayToWorkingHours.Designer.cs @@ -0,0 +1,648 @@ +// +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("20251202113519_IsActiveDayToWorkingHours")] + partial class IsActiveDayToWorkingHours + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.CustomerAgg.Customer", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("Customers", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("HasAssignmentOverride") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("PlannedEndDate") + .HasColumnType("datetime2"); + + b.Property("PlannedStartDate") + .HasColumnType("datetime2"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.ToTable("Projects", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("HasAssignmentOverride") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("OrderIndex") + .HasColumnType("int"); + + b.Property("ProjectId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.ToTable("ProjectPhases", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("CurrentAssignedUserId") + .HasColumnType("bigint"); + + b.Property("InitialDescription") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("InitialEstimatedHours") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("SkillId") + .HasColumnType("uniqueidentifier"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("TaskId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("SkillId"); + + b.HasIndex("TaskId"); + + b.ToTable("ProjectSections", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSectionActivity", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("EndNotes") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("Notes") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("SectionId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("SectionId"); + + b.ToTable("ProjectSectionActivities", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSectionAdditionalTime", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AddedAt") + .HasColumnType("datetime2"); + + b.Property("AddedByUserId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Hours") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("ProjectSectionId") + .HasColumnType("uniqueidentifier"); + + b.Property("Reason") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.HasKey("Id"); + + b.HasIndex("ProjectSectionId"); + + b.ToTable("ProjectSectionAdditionalTimes", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AllocatedTime") + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("DueDate") + .HasColumnType("datetime2"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("HasAssignmentOverride") + .HasColumnType("bit"); + + b.Property("HasTimeOverride") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("OrderIndex") + .HasColumnType("int"); + + b.Property("PhaseId") + .HasColumnType("uniqueidentifier"); + + b.Property("Priority") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.HasIndex("PhaseId"); + + b.ToTable("ProjectTasks", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.RoleAgg.Entities.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("GozareshgirRoleId") + .HasColumnType("bigint"); + + b.Property("RoleName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.HasKey("Id"); + + b.ToTable("Roles", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities.SalaryPaymentSetting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("EndSettingDate") + .HasColumnType("datetime2"); + + b.Property("HolidayWorking") + .HasColumnType("bit"); + + b.Property("MonthlySalary") + .HasColumnType("float"); + + b.Property("StartSettingDate") + .HasColumnType("datetime2"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.ToTable("SalaryPaymentSetting", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("Skills", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .HasMaxLength(150) + .HasColumnType("nvarchar(150)"); + + b.Property("FullName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("Mobile") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.Property("Password") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("ProfilePhotoPath") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("VerifyCode") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.HasKey("Id"); + + b.ToTable("Users", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.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.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.ProjectSectionActivity", 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.ProjectSectionAdditionalTime", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", null) + .WithMany("AdditionalTimes") + .HasForeignKey("ProjectSectionId"); + }); + + 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.RoleAgg.Entities.Role", b => + { + b.OwnsMany("GozareshgirProgramManager.Domain.PermissionAgg.Entities.Permission", "Permissions", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("Code") + .HasColumnType("int"); + + b1.Property("RoleId") + .HasColumnType("bigint"); + + b1.HasKey("Id"); + + b1.HasIndex("RoleId"); + + b1.ToTable("RolePermissions", (string)null); + + b1.WithOwner("Role") + .HasForeignKey("RoleId"); + + b1.Navigation("Role"); + }); + + b.Navigation("Permissions"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities.SalaryPaymentSetting", b => + { + b.OwnsMany("GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities.WorkingHours", "WorkingHoursList", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("EndShiftOne") + .HasColumnType("time(0)"); + + b1.Property("EndShiftTwo") + .HasColumnType("time(0)"); + + b1.Property("HasRestTime") + .HasColumnType("bit"); + + b1.Property("HasShiftOne") + .HasColumnType("bit"); + + b1.Property("HasShiftTow") + .HasColumnType("bit"); + + b1.Property("IsActiveDay") + .HasColumnType("bit"); + + b1.Property("PersianDayOfWeek") + .HasColumnType("int"); + + b1.Property("RestTime") + .HasColumnType("time(0)"); + + b1.Property("SalaryPaymentSettingId") + .HasColumnType("bigint"); + + b1.Property("ShiftDurationInMinutes") + .HasColumnType("int"); + + b1.Property("StartShiftOne") + .HasColumnType("time(0)"); + + b1.Property("StartShiftTwo") + .HasColumnType("time(0)"); + + b1.HasKey("Id"); + + b1.HasIndex("SalaryPaymentSettingId"); + + b1.ToTable("WorkingHours", (string)null); + + b1.WithOwner("SalaryPaymentSetting") + .HasForeignKey("SalaryPaymentSettingId"); + + b1.Navigation("SalaryPaymentSetting"); + }); + + b.Navigation("WorkingHoursList"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b => + { + b.OwnsMany("GozareshgirProgramManager.Domain.RoleUserAgg.RoleUser", "RoleUser", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("RoleId") + .HasColumnType("bigint"); + + b1.Property("UserId") + .HasColumnType("bigint"); + + b1.HasKey("Id"); + + b1.HasIndex("UserId"); + + b1.ToTable("RoleUsers", (string)null); + + b1.WithOwner("User") + .HasForeignKey("UserId"); + + b1.Navigation("User"); + }); + + b.Navigation("RoleUser"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project", b => + { + b.Navigation("Phases"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", b => + { + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.Navigation("Activities"); + + b.Navigation("AdditionalTimes"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", b => + { + b.Navigation("Sections"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", b => + { + b.Navigation("Sections"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251202113519_IsActiveDayToWorkingHours.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251202113519_IsActiveDayToWorkingHours.cs new file mode 100644 index 00000000..8e4cf65f --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251202113519_IsActiveDayToWorkingHours.cs @@ -0,0 +1,29 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace GozareshgirProgramManager.Infrastructure.Migrations +{ + /// + public partial class IsActiveDayToWorkingHours : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "IsActiveDay", + table: "WorkingHours", + type: "bit", + nullable: false, + defaultValue: false); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "IsActiveDay", + table: "WorkingHours"); + } + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251202145954_CheckoutInit.Designer.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251202145954_CheckoutInit.Designer.cs new file mode 100644 index 00000000..a529f983 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251202145954_CheckoutInit.Designer.cs @@ -0,0 +1,706 @@ +// +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("20251202145954_CheckoutInit")] + partial class CheckoutInit + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.CheckoutAgg.Entities.Checkout", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CheckoutEndDate") + .HasColumnType("datetime2"); + + b.Property("CheckoutStartDate") + .HasColumnType("datetime2"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("DeductionFromSalary") + .HasColumnType("float"); + + b.Property("FullName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("MandatoryHours") + .HasColumnType("int"); + + b.Property("Month") + .HasColumnType("int"); + + b.Property("MonthlySalaryDefined") + .HasColumnType("float"); + + b.Property("MonthlySalaryPay") + .HasColumnType("float"); + + b.Property("RemainingHours") + .HasColumnType("int"); + + b.Property("TotalDaysWorked") + .HasColumnType("int"); + + b.Property("TotalHoursWorked") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.Property("Year") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Checkouts", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.CustomerAgg.Customer", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("Customers", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("HasAssignmentOverride") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("PlannedEndDate") + .HasColumnType("datetime2"); + + b.Property("PlannedStartDate") + .HasColumnType("datetime2"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.ToTable("Projects", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("HasAssignmentOverride") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("OrderIndex") + .HasColumnType("int"); + + b.Property("ProjectId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.ToTable("ProjectPhases", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSection", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("CurrentAssignedUserId") + .HasColumnType("bigint"); + + b.Property("InitialDescription") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("InitialEstimatedHours") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("OriginalAssignedUserId") + .HasColumnType("bigint"); + + b.Property("SkillId") + .HasColumnType("uniqueidentifier"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("TaskId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("SkillId"); + + b.HasIndex("TaskId"); + + b.ToTable("ProjectSections", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSectionActivity", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("EndNotes") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("Notes") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("SectionId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("SectionId"); + + b.ToTable("ProjectSectionActivities", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSectionAdditionalTime", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AddedAt") + .HasColumnType("datetime2"); + + b.Property("AddedByUserId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Hours") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("ProjectSectionId") + .HasColumnType("uniqueidentifier"); + + b.Property("Reason") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.HasKey("Id"); + + b.HasIndex("ProjectSectionId"); + + b.ToTable("ProjectSectionAdditionalTimes", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AllocatedTime") + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("DueDate") + .HasColumnType("datetime2"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("HasAssignmentOverride") + .HasColumnType("bit"); + + b.Property("HasTimeOverride") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("OrderIndex") + .HasColumnType("int"); + + b.Property("PhaseId") + .HasColumnType("uniqueidentifier"); + + b.Property("Priority") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.HasIndex("PhaseId"); + + b.ToTable("ProjectTasks", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.RoleAgg.Entities.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("GozareshgirRoleId") + .HasColumnType("bigint"); + + b.Property("RoleName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.HasKey("Id"); + + b.ToTable("Roles", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities.SalaryPaymentSetting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("EndSettingDate") + .HasColumnType("datetime2"); + + b.Property("HolidayWorking") + .HasColumnType("bit"); + + b.Property("MonthlySalary") + .HasColumnType("float"); + + b.Property("StartSettingDate") + .HasColumnType("datetime2"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.ToTable("SalaryPaymentSetting", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("Skills", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .HasMaxLength(150) + .HasColumnType("nvarchar(150)"); + + b.Property("FullName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("Mobile") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.Property("Password") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("ProfilePhotoPath") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("VerifyCode") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.HasKey("Id"); + + b.ToTable("Users", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.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.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.ProjectSectionActivity", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSection", "Section") + .WithMany("Activities") + .HasForeignKey("SectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Section"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSectionAdditionalTime", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSection", null) + .WithMany("AdditionalTimes") + .HasForeignKey("ProjectSectionId"); + }); + + 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.RoleAgg.Entities.Role", b => + { + b.OwnsMany("GozareshgirProgramManager.Domain.PermissionAgg.Entities.Permission", "Permissions", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("Code") + .HasColumnType("int"); + + b1.Property("RoleId") + .HasColumnType("bigint"); + + b1.HasKey("Id"); + + b1.HasIndex("RoleId"); + + b1.ToTable("RolePermissions", (string)null); + + b1.WithOwner("Role") + .HasForeignKey("RoleId"); + + b1.Navigation("Role"); + }); + + b.Navigation("Permissions"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities.SalaryPaymentSetting", b => + { + b.OwnsMany("GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities.WorkingHours", "WorkingHoursList", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("EndShiftOne") + .HasColumnType("time(0)"); + + b1.Property("EndShiftTwo") + .HasColumnType("time(0)"); + + b1.Property("HasRestTime") + .HasColumnType("bit"); + + b1.Property("HasShiftOne") + .HasColumnType("bit"); + + b1.Property("HasShiftTow") + .HasColumnType("bit"); + + b1.Property("IsActiveDay") + .HasColumnType("bit"); + + b1.Property("PersianDayOfWeek") + .HasColumnType("int"); + + b1.Property("RestTime") + .HasColumnType("time(0)"); + + b1.Property("SalaryPaymentSettingId") + .HasColumnType("bigint"); + + b1.Property("ShiftDurationInMinutes") + .HasColumnType("int"); + + b1.Property("StartShiftOne") + .HasColumnType("time(0)"); + + b1.Property("StartShiftTwo") + .HasColumnType("time(0)"); + + b1.HasKey("Id"); + + b1.HasIndex("SalaryPaymentSettingId"); + + b1.ToTable("WorkingHours", (string)null); + + b1.WithOwner("SalaryPaymentSetting") + .HasForeignKey("SalaryPaymentSettingId"); + + b1.Navigation("SalaryPaymentSetting"); + }); + + b.Navigation("WorkingHoursList"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b => + { + b.OwnsMany("GozareshgirProgramManager.Domain.RoleUserAgg.RoleUser", "RoleUser", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("RoleId") + .HasColumnType("bigint"); + + b1.Property("UserId") + .HasColumnType("bigint"); + + b1.HasKey("Id"); + + b1.HasIndex("UserId"); + + b1.ToTable("RoleUsers", (string)null); + + b1.WithOwner("User") + .HasForeignKey("UserId"); + + b1.Navigation("User"); + }); + + b.Navigation("RoleUser"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project", b => + { + b.Navigation("Phases"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", b => + { + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSection", b => + { + b.Navigation("Activities"); + + b.Navigation("AdditionalTimes"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", b => + { + b.Navigation("Sections"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", b => + { + b.Navigation("Sections"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251202145954_CheckoutInit.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251202145954_CheckoutInit.cs new file mode 100644 index 00000000..8aa33809 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251202145954_CheckoutInit.cs @@ -0,0 +1,50 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace GozareshgirProgramManager.Infrastructure.Migrations +{ + /// + public partial class CheckoutInit : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + + + migrationBuilder.CreateTable( + name: "Checkouts", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + CheckoutStartDate = table.Column(type: "datetime2", nullable: false), + CheckoutEndDate = table.Column(type: "datetime2", nullable: false), + Year = table.Column(type: "int", nullable: false), + Month = table.Column(type: "int", nullable: false), + FullName = table.Column(type: "nvarchar(100)", maxLength: 100, nullable: false), + UserId = table.Column(type: "bigint", nullable: false), + MandatoryHours = table.Column(type: "int", nullable: false), + TotalHoursWorked = table.Column(type: "int", nullable: false), + TotalDaysWorked = table.Column(type: "int", nullable: false), + RemainingHours = table.Column(type: "int", nullable: false), + MonthlySalaryDefined = table.Column(type: "float", nullable: false), + MonthlySalaryPay = table.Column(type: "float", nullable: false), + DeductionFromSalary = table.Column(type: "float", nullable: false), + CreationDate = table.Column(type: "datetime2", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Checkouts", x => x.Id); + }); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Checkouts"); + + } + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251203071011_add user refresh token.Designer.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251203071011_add user refresh token.Designer.cs new file mode 100644 index 00000000..3d7eedab --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251203071011_add user refresh token.Designer.cs @@ -0,0 +1,707 @@ +// +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("20251203071011_add user refresh token")] + partial class adduserrefreshtoken + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.CustomerAgg.Customer", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("Customers", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("HasAssignmentOverride") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("PlannedEndDate") + .HasColumnType("datetime2"); + + b.Property("PlannedStartDate") + .HasColumnType("datetime2"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.ToTable("Projects", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("HasAssignmentOverride") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("OrderIndex") + .HasColumnType("int"); + + b.Property("ProjectId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.ToTable("ProjectPhases", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("CurrentAssignedUserId") + .HasColumnType("bigint"); + + b.Property("InitialDescription") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("InitialEstimatedHours") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("OriginalAssignedUserId") + .HasColumnType("bigint"); + + b.Property("SkillId") + .HasColumnType("uniqueidentifier"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("TaskId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("SkillId"); + + b.HasIndex("TaskId"); + + b.ToTable("ProjectSections", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSectionActivity", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("EndNotes") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("Notes") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("SectionId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("SectionId"); + + b.ToTable("ProjectSectionActivities", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSectionAdditionalTime", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AddedAt") + .HasColumnType("datetime2"); + + b.Property("AddedByUserId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Hours") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("ProjectSectionId") + .HasColumnType("uniqueidentifier"); + + b.Property("Reason") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.HasKey("Id"); + + b.HasIndex("ProjectSectionId"); + + b.ToTable("ProjectSectionAdditionalTimes", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AllocatedTime") + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("DueDate") + .HasColumnType("datetime2"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("HasAssignmentOverride") + .HasColumnType("bit"); + + b.Property("HasTimeOverride") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("OrderIndex") + .HasColumnType("int"); + + b.Property("PhaseId") + .HasColumnType("uniqueidentifier"); + + b.Property("Priority") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.HasIndex("PhaseId"); + + b.ToTable("ProjectTasks", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.RoleAgg.Entities.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("GozareshgirRoleId") + .HasColumnType("bigint"); + + b.Property("RoleName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.HasKey("Id"); + + b.ToTable("Roles", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities.SalaryPaymentSetting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("EndSettingDate") + .HasColumnType("datetime2"); + + b.Property("HolidayWorking") + .HasColumnType("bit"); + + b.Property("MonthlySalary") + .HasColumnType("float"); + + b.Property("StartSettingDate") + .HasColumnType("datetime2"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.ToTable("SalaryPaymentSetting", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("Skills", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .HasMaxLength(150) + .HasColumnType("nvarchar(150)"); + + b.Property("FullName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("Mobile") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.Property("Password") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("ProfilePhotoPath") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("VerifyCode") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.HasKey("Id"); + + b.ToTable("Users", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.UserRefreshToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("ExpiresAt") + .HasColumnType("datetime2"); + + b.Property("IpAddress") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("RevokedAt") + .HasColumnType("datetime2"); + + b.Property("Token") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UserAgent") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("ExpiresAt"); + + b.HasIndex("Token") + .IsUnique(); + + b.HasIndex("UserId"); + + b.ToTable("UserRefreshTokens", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.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.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.ProjectSectionActivity", 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.ProjectSectionAdditionalTime", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", null) + .WithMany("AdditionalTimes") + .HasForeignKey("ProjectSectionId"); + }); + + 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.RoleAgg.Entities.Role", b => + { + b.OwnsMany("GozareshgirProgramManager.Domain.PermissionAgg.Entities.Permission", "Permissions", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("Code") + .HasColumnType("int"); + + b1.Property("RoleId") + .HasColumnType("bigint"); + + b1.HasKey("Id"); + + b1.HasIndex("RoleId"); + + b1.ToTable("RolePermissions", (string)null); + + b1.WithOwner("Role") + .HasForeignKey("RoleId"); + + b1.Navigation("Role"); + }); + + b.Navigation("Permissions"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities.SalaryPaymentSetting", b => + { + b.OwnsMany("GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities.WorkingHours", "WorkingHoursList", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("EndShiftOne") + .HasColumnType("time(0)"); + + b1.Property("EndShiftTwo") + .HasColumnType("time(0)"); + + b1.Property("HasRestTime") + .HasColumnType("bit"); + + b1.Property("HasShiftOne") + .HasColumnType("bit"); + + b1.Property("HasShiftTow") + .HasColumnType("bit"); + + b1.Property("PersianDayOfWeek") + .HasColumnType("int"); + + b1.Property("RestTime") + .HasColumnType("time(0)"); + + b1.Property("SalaryPaymentSettingId") + .HasColumnType("bigint"); + + b1.Property("ShiftDurationInMinutes") + .HasColumnType("int"); + + b1.Property("StartShiftOne") + .HasColumnType("time(0)"); + + b1.Property("StartShiftTwo") + .HasColumnType("time(0)"); + + b1.HasKey("Id"); + + b1.HasIndex("SalaryPaymentSettingId"); + + b1.ToTable("WorkingHours", (string)null); + + b1.WithOwner("SalaryPaymentSetting") + .HasForeignKey("SalaryPaymentSettingId"); + + b1.Navigation("SalaryPaymentSetting"); + }); + + b.Navigation("WorkingHoursList"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b => + { + b.OwnsMany("GozareshgirProgramManager.Domain.RoleUserAgg.RoleUser", "RoleUser", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("RoleId") + .HasColumnType("bigint"); + + b1.Property("UserId") + .HasColumnType("bigint"); + + b1.HasKey("Id"); + + b1.HasIndex("UserId"); + + b1.ToTable("RoleUsers", (string)null); + + b1.WithOwner("User") + .HasForeignKey("UserId"); + + b1.Navigation("User"); + }); + + b.Navigation("RoleUser"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.UserRefreshToken", b => + { + b.HasOne("GozareshgirProgramManager.Domain.UserAgg.Entities.User", "User") + .WithMany("RefreshTokens") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project", b => + { + b.Navigation("Phases"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", b => + { + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.Navigation("Activities"); + + b.Navigation("AdditionalTimes"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", b => + { + b.Navigation("Sections"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", b => + { + b.Navigation("Sections"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b => + { + b.Navigation("RefreshTokens"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251203071011_add user refresh token.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251203071011_add user refresh token.cs new file mode 100644 index 00000000..c4e6c962 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251203071011_add user refresh token.cs @@ -0,0 +1,62 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace GozareshgirProgramManager.Infrastructure.Migrations +{ + /// + public partial class adduserrefreshtoken : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "UserRefreshTokens", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + UserId = table.Column(type: "bigint", nullable: false), + Token = table.Column(type: "nvarchar(500)", maxLength: 500, nullable: false), + ExpiresAt = table.Column(type: "datetime2", nullable: false), + RevokedAt = table.Column(type: "datetime2", nullable: true), + IpAddress = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: true), + UserAgent = table.Column(type: "nvarchar(500)", maxLength: 500, nullable: true), + CreationDate = table.Column(type: "datetime2", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_UserRefreshTokens", x => x.Id); + table.ForeignKey( + name: "FK_UserRefreshTokens_Users_UserId", + column: x => x.UserId, + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_UserRefreshTokens_ExpiresAt", + table: "UserRefreshTokens", + column: "ExpiresAt"); + + migrationBuilder.CreateIndex( + name: "IX_UserRefreshTokens_Token", + table: "UserRefreshTokens", + column: "Token", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_UserRefreshTokens_UserId", + table: "UserRefreshTokens", + column: "UserId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "UserRefreshTokens"); + } + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251203174140_add sections.Designer.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251203174140_add sections.Designer.cs new file mode 100644 index 00000000..902c1fb7 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251203174140_add sections.Designer.cs @@ -0,0 +1,786 @@ +// +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("20251203174140_add sections")] + partial class addsections + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.CustomerAgg.Customer", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("Customers", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.PhaseSection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("PhaseId") + .HasColumnType("uniqueidentifier"); + + b.Property("SkillId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("PhaseId"); + + b.ToTable("PhaseSection"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("HasAssignmentOverride") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("PlannedEndDate") + .HasColumnType("datetime2"); + + b.Property("PlannedStartDate") + .HasColumnType("datetime2"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.ToTable("Projects", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("HasAssignmentOverride") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("OrderIndex") + .HasColumnType("int"); + + b.Property("ProjectId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.ToTable("ProjectPhases", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("ProjectId") + .HasColumnType("uniqueidentifier"); + + b.Property("SkillId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.ToTable("ProjectSection"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AllocatedTime") + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("DueDate") + .HasColumnType("datetime2"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("HasAssignmentOverride") + .HasColumnType("bit"); + + b.Property("HasTimeOverride") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("OrderIndex") + .HasColumnType("int"); + + b.Property("PhaseId") + .HasColumnType("uniqueidentifier"); + + b.Property("Priority") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.HasIndex("PhaseId"); + + b.ToTable("ProjectTasks", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("CurrentAssignedUserId") + .HasColumnType("bigint"); + + b.Property("InitialDescription") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("InitialEstimatedHours") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("OriginalAssignedUserId") + .HasColumnType("bigint"); + + b.Property("SkillId") + .HasColumnType("uniqueidentifier"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("TaskId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("SkillId"); + + b.HasIndex("TaskId"); + + b.ToTable("TaskSections", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSectionActivity", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("EndNotes") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("Notes") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("SectionId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("SectionId"); + + b.ToTable("TaskSectionActivities", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSectionAdditionalTime", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AddedAt") + .HasColumnType("datetime2"); + + b.Property("AddedByUserId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Hours") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("Reason") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("TaskSectionId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("TaskSectionId"); + + b.ToTable("TaskSectionAdditionalTimes", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.RoleAgg.Entities.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("GozareshgirRoleId") + .HasColumnType("bigint"); + + b.Property("RoleName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.HasKey("Id"); + + b.ToTable("Roles", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities.SalaryPaymentSetting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("EndSettingDate") + .HasColumnType("datetime2"); + + b.Property("HolidayWorking") + .HasColumnType("bit"); + + b.Property("MonthlySalary") + .HasColumnType("float"); + + b.Property("StartSettingDate") + .HasColumnType("datetime2"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.ToTable("SalaryPaymentSetting", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("Skills", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .HasMaxLength(150) + .HasColumnType("nvarchar(150)"); + + b.Property("FullName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("Mobile") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.Property("Password") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("ProfilePhotoPath") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("VerifyCode") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.HasKey("Id"); + + b.ToTable("Users", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.UserRefreshToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("ExpiresAt") + .HasColumnType("datetime2"); + + b.Property("IpAddress") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("RevokedAt") + .HasColumnType("datetime2"); + + b.Property("Token") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UserAgent") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("ExpiresAt"); + + b.HasIndex("Token") + .IsUnique(); + + b.HasIndex("UserId"); + + b.ToTable("UserRefreshTokens", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.PhaseSection", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", "Phase") + .WithMany("PhaseSections") + .HasForeignKey("PhaseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Phase"); + }); + + 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.Navigation("Project"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", "Phase") + .WithMany("Tasks") + .HasForeignKey("PhaseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Phase"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.HasOne("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", "Skill") + .WithMany("Sections") + .HasForeignKey("SkillId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", "Task") + .WithMany("Sections") + .HasForeignKey("TaskId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Skill"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSectionActivity", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", "Section") + .WithMany("Activities") + .HasForeignKey("SectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Section"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSectionAdditionalTime", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", null) + .WithMany("AdditionalTimes") + .HasForeignKey("TaskSectionId"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.RoleAgg.Entities.Role", b => + { + b.OwnsMany("GozareshgirProgramManager.Domain.PermissionAgg.Entities.Permission", "Permissions", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("Code") + .HasColumnType("int"); + + b1.Property("RoleId") + .HasColumnType("bigint"); + + b1.HasKey("Id"); + + b1.HasIndex("RoleId"); + + b1.ToTable("RolePermissions", (string)null); + + b1.WithOwner("Role") + .HasForeignKey("RoleId"); + + b1.Navigation("Role"); + }); + + b.Navigation("Permissions"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities.SalaryPaymentSetting", b => + { + b.OwnsMany("GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities.WorkingHours", "WorkingHoursList", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("EndShiftOne") + .HasColumnType("time(0)"); + + b1.Property("EndShiftTwo") + .HasColumnType("time(0)"); + + b1.Property("HasRestTime") + .HasColumnType("bit"); + + b1.Property("HasShiftOne") + .HasColumnType("bit"); + + b1.Property("HasShiftTow") + .HasColumnType("bit"); + + b1.Property("IsActiveDay") + .HasColumnType("bit"); + + b1.Property("PersianDayOfWeek") + .HasColumnType("int"); + + b1.Property("RestTime") + .HasColumnType("time(0)"); + + b1.Property("SalaryPaymentSettingId") + .HasColumnType("bigint"); + + b1.Property("ShiftDurationInMinutes") + .HasColumnType("int"); + + b1.Property("StartShiftOne") + .HasColumnType("time(0)"); + + b1.Property("StartShiftTwo") + .HasColumnType("time(0)"); + + b1.HasKey("Id"); + + b1.HasIndex("SalaryPaymentSettingId"); + + b1.ToTable("WorkingHours", (string)null); + + b1.WithOwner("SalaryPaymentSetting") + .HasForeignKey("SalaryPaymentSettingId"); + + b1.Navigation("SalaryPaymentSetting"); + }); + + b.Navigation("WorkingHoursList"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b => + { + b.OwnsMany("GozareshgirProgramManager.Domain.RoleUserAgg.RoleUser", "RoleUser", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("RoleId") + .HasColumnType("bigint"); + + b1.Property("UserId") + .HasColumnType("bigint"); + + b1.HasKey("Id"); + + b1.HasIndex("UserId"); + + b1.ToTable("RoleUsers", (string)null); + + b1.WithOwner("User") + .HasForeignKey("UserId"); + + b1.Navigation("User"); + }); + + b.Navigation("RoleUser"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.UserRefreshToken", b => + { + b.HasOne("GozareshgirProgramManager.Domain.UserAgg.Entities.User", "User") + .WithMany("RefreshTokens") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project", b => + { + b.Navigation("Phases"); + + b.Navigation("ProjectSections"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", b => + { + b.Navigation("PhaseSections"); + + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", b => + { + b.Navigation("Sections"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.Navigation("Activities"); + + b.Navigation("AdditionalTimes"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", b => + { + b.Navigation("Sections"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b => + { + b.Navigation("RefreshTokens"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251203174140_add sections.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251203174140_add sections.cs new file mode 100644 index 00000000..fb691678 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251203174140_add sections.cs @@ -0,0 +1,288 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace GozareshgirProgramManager.Infrastructure.Migrations +{ + /// + public partial class addsections : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + + + migrationBuilder.DropForeignKey( + name: "FK_ProjectSections_Skills_SkillId", + table: "ProjectSections"); + + migrationBuilder.DropTable( + name: "ProjectSectionActivities"); + + migrationBuilder.DropTable( + name: "ProjectSectionAdditionalTimes"); + + migrationBuilder.DropPrimaryKey( + name: "PK_ProjectSections", + table: "ProjectSections"); + + migrationBuilder.RenameTable( + name: "ProjectSections", + newName: "TaskSections"); + + migrationBuilder.RenameIndex( + name: "IX_ProjectSections_TaskId", + table: "TaskSections", + newName: "IX_TaskSections_TaskId"); + + migrationBuilder.RenameIndex( + name: "IX_ProjectSections_SkillId", + table: "TaskSections", + newName: "IX_TaskSections_SkillId"); + + migrationBuilder.AddPrimaryKey( + name: "PK_TaskSections", + table: "TaskSections", + column: "Id"); + + migrationBuilder.CreateTable( + name: "PhaseSection", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + PhaseId = table.Column(type: "uniqueidentifier", nullable: false), + UserId = table.Column(type: "bigint", nullable: false), + SkillId = table.Column(type: "uniqueidentifier", nullable: false), + CreationDate = table.Column(type: "datetime2", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_PhaseSection", x => x.Id); + table.ForeignKey( + name: "FK_PhaseSection_ProjectPhases_PhaseId", + column: x => x.PhaseId, + principalTable: "ProjectPhases", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ProjectSection", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + ProjectId = table.Column(type: "uniqueidentifier", nullable: false), + UserId = table.Column(type: "bigint", nullable: false), + SkillId = table.Column(type: "uniqueidentifier", nullable: false), + CreationDate = table.Column(type: "datetime2", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ProjectSection", x => x.Id); + table.ForeignKey( + name: "FK_ProjectSection_Projects_ProjectId", + column: x => x.ProjectId, + principalTable: "Projects", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "TaskSectionActivities", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + SectionId = table.Column(type: "uniqueidentifier", nullable: false), + UserId = table.Column(type: "bigint", nullable: false), + StartDate = table.Column(type: "datetime2", nullable: false), + EndDate = table.Column(type: "datetime2", nullable: true), + Notes = table.Column(type: "nvarchar(1000)", maxLength: 1000, nullable: true), + EndNotes = table.Column(type: "nvarchar(1000)", maxLength: 1000, nullable: true), + IsActive = table.Column(type: "bit", nullable: false), + CreationDate = table.Column(type: "datetime2", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_TaskSectionActivities", x => x.Id); + table.ForeignKey( + name: "FK_TaskSectionActivities_TaskSections_SectionId", + column: x => x.SectionId, + principalTable: "TaskSections", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "TaskSectionAdditionalTimes", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + Hours = table.Column(type: "nvarchar(30)", maxLength: 30, nullable: false), + Reason = table.Column(type: "nvarchar(500)", maxLength: 500, nullable: true), + AddedByUserId = table.Column(type: "bigint", nullable: true), + AddedAt = table.Column(type: "datetime2", nullable: false), + TaskSectionId = table.Column(type: "uniqueidentifier", nullable: true), + CreationDate = table.Column(type: "datetime2", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_TaskSectionAdditionalTimes", x => x.Id); + table.ForeignKey( + name: "FK_TaskSectionAdditionalTimes_TaskSections_TaskSectionId", + column: x => x.TaskSectionId, + principalTable: "TaskSections", + principalColumn: "Id"); + }); + + migrationBuilder.CreateIndex( + name: "IX_PhaseSection_PhaseId", + table: "PhaseSection", + column: "PhaseId"); + + migrationBuilder.CreateIndex( + name: "IX_ProjectSection_ProjectId", + table: "ProjectSection", + column: "ProjectId"); + + migrationBuilder.CreateIndex( + name: "IX_TaskSectionActivities_SectionId", + table: "TaskSectionActivities", + column: "SectionId"); + + migrationBuilder.CreateIndex( + name: "IX_TaskSectionAdditionalTimes_TaskSectionId", + table: "TaskSectionAdditionalTimes", + column: "TaskSectionId"); + + migrationBuilder.AddForeignKey( + name: "FK_TaskSections_ProjectTasks_TaskId", + table: "TaskSections", + column: "TaskId", + principalTable: "ProjectTasks", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_TaskSections_Skills_SkillId", + table: "TaskSections", + column: "SkillId", + principalTable: "Skills", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_TaskSections_ProjectTasks_TaskId", + table: "TaskSections"); + + migrationBuilder.DropForeignKey( + name: "FK_TaskSections_Skills_SkillId", + table: "TaskSections"); + + migrationBuilder.DropTable( + name: "PhaseSection"); + + migrationBuilder.DropTable( + name: "ProjectSection"); + + migrationBuilder.DropTable( + name: "TaskSectionActivities"); + + migrationBuilder.DropTable( + name: "TaskSectionAdditionalTimes"); + + migrationBuilder.DropPrimaryKey( + name: "PK_TaskSections", + table: "TaskSections"); + + migrationBuilder.RenameTable( + name: "TaskSections", + newName: "ProjectSections"); + + migrationBuilder.RenameIndex( + name: "IX_TaskSections_TaskId", + table: "ProjectSections", + newName: "IX_ProjectSections_TaskId"); + + migrationBuilder.RenameIndex( + name: "IX_TaskSections_SkillId", + table: "ProjectSections", + newName: "IX_ProjectSections_SkillId"); + + migrationBuilder.AddPrimaryKey( + name: "PK_ProjectSections", + table: "ProjectSections", + column: "Id"); + + migrationBuilder.CreateTable( + name: "ProjectSectionActivities", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + SectionId = table.Column(type: "uniqueidentifier", nullable: false), + CreationDate = table.Column(type: "datetime2", nullable: false), + EndDate = table.Column(type: "datetime2", nullable: true), + EndNotes = table.Column(type: "nvarchar(1000)", maxLength: 1000, nullable: true), + IsActive = table.Column(type: "bit", nullable: false), + Notes = table.Column(type: "nvarchar(1000)", maxLength: 1000, nullable: true), + StartDate = table.Column(type: "datetime2", nullable: false), + UserId = table.Column(type: "bigint", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ProjectSectionActivities", x => x.Id); + table.ForeignKey( + name: "FK_ProjectSectionActivities_ProjectSections_SectionId", + column: x => x.SectionId, + principalTable: "ProjectSections", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ProjectSectionAdditionalTimes", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + AddedAt = table.Column(type: "datetime2", nullable: false), + AddedByUserId = table.Column(type: "bigint", nullable: true), + CreationDate = table.Column(type: "datetime2", nullable: false), + Hours = table.Column(type: "nvarchar(30)", maxLength: 30, nullable: false), + ProjectSectionId = table.Column(type: "uniqueidentifier", nullable: true), + Reason = table.Column(type: "nvarchar(500)", maxLength: 500, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_ProjectSectionAdditionalTimes", x => x.Id); + table.ForeignKey( + name: "FK_ProjectSectionAdditionalTimes_ProjectSections_ProjectSectionId", + column: x => x.ProjectSectionId, + principalTable: "ProjectSections", + principalColumn: "Id"); + }); + + migrationBuilder.CreateIndex( + name: "IX_ProjectSectionActivities_SectionId", + table: "ProjectSectionActivities", + column: "SectionId"); + + migrationBuilder.CreateIndex( + name: "IX_ProjectSectionAdditionalTimes_ProjectSectionId", + table: "ProjectSectionAdditionalTimes", + column: "ProjectSectionId"); + + + migrationBuilder.AddForeignKey( + name: "FK_ProjectSections_Skills_SkillId", + table: "ProjectSections", + column: "SkillId", + principalTable: "Skills", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251206064818_add phase section and task section.Designer.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251206064818_add phase section and task section.Designer.cs new file mode 100644 index 00000000..4de07c56 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251206064818_add phase section and task section.Designer.cs @@ -0,0 +1,839 @@ +// +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("20251206064818_add phase section and task section")] + partial class addphasesectionandtasksection + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.CheckoutAgg.Entities.Checkout", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CheckoutEndDate") + .HasColumnType("datetime2"); + + b.Property("CheckoutStartDate") + .HasColumnType("datetime2"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("DeductionFromSalary") + .HasColumnType("float"); + + b.Property("FullName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("MandatoryHours") + .HasColumnType("int"); + + b.Property("Month") + .HasColumnType("int"); + + b.Property("MonthlySalaryDefined") + .HasColumnType("float"); + + b.Property("MonthlySalaryPay") + .HasColumnType("float"); + + b.Property("RemainingHours") + .HasColumnType("int"); + + b.Property("TotalDaysWorked") + .HasColumnType("int"); + + b.Property("TotalHoursWorked") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.Property("Year") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Checkouts", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.CustomerAgg.Customer", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("Customers", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.PhaseSection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("PhaseId") + .HasColumnType("uniqueidentifier"); + + b.Property("SkillId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("PhaseId"); + + b.ToTable("PhaseSections"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("HasAssignmentOverride") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("PlannedEndDate") + .HasColumnType("datetime2"); + + b.Property("PlannedStartDate") + .HasColumnType("datetime2"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.ToTable("Projects", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("HasAssignmentOverride") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("OrderIndex") + .HasColumnType("int"); + + b.Property("ProjectId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.ToTable("ProjectPhases", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSection", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("ProjectId") + .HasColumnType("uniqueidentifier"); + + b.Property("SkillId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.ToTable("ProjectSections"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AllocatedTime") + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("DueDate") + .HasColumnType("datetime2"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("HasAssignmentOverride") + .HasColumnType("bit"); + + b.Property("HasTimeOverride") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("OrderIndex") + .HasColumnType("int"); + + b.Property("PhaseId") + .HasColumnType("uniqueidentifier"); + + b.Property("Priority") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.HasIndex("PhaseId"); + + b.ToTable("ProjectTasks", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("CurrentAssignedUserId") + .HasColumnType("bigint"); + + b.Property("InitialDescription") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("InitialEstimatedHours") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("OriginalAssignedUserId") + .HasColumnType("bigint"); + + b.Property("SkillId") + .HasColumnType("uniqueidentifier"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("TaskId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("SkillId"); + + b.HasIndex("TaskId"); + + b.ToTable("TaskSections", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSectionActivity", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("EndNotes") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("Notes") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("SectionId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("SectionId"); + + b.ToTable("TaskSectionActivities", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSectionAdditionalTime", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AddedAt") + .HasColumnType("datetime2"); + + b.Property("AddedByUserId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Hours") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("Reason") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("TaskSectionId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("TaskSectionId"); + + b.ToTable("TaskSectionAdditionalTimes", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.RoleAgg.Entities.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("GozareshgirRoleId") + .HasColumnType("bigint"); + + b.Property("RoleName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.HasKey("Id"); + + b.ToTable("Roles", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities.SalaryPaymentSetting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("EndSettingDate") + .HasColumnType("datetime2"); + + b.Property("HolidayWorking") + .HasColumnType("bit"); + + b.Property("MonthlySalary") + .HasColumnType("float"); + + b.Property("StartSettingDate") + .HasColumnType("datetime2"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.ToTable("SalaryPaymentSetting", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("Skills", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .HasMaxLength(150) + .HasColumnType("nvarchar(150)"); + + b.Property("FullName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("Mobile") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.Property("Password") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("ProfilePhotoPath") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("VerifyCode") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.HasKey("Id"); + + b.ToTable("Users", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.UserRefreshToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("ExpiresAt") + .HasColumnType("datetime2"); + + b.Property("IpAddress") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("RevokedAt") + .HasColumnType("datetime2"); + + b.Property("Token") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UserAgent") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("ExpiresAt"); + + b.HasIndex("Token") + .IsUnique(); + + b.HasIndex("UserId"); + + b.ToTable("UserRefreshTokens", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.PhaseSection", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", "Phase") + .WithMany("PhaseSections") + .HasForeignKey("PhaseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Phase"); + }); + + 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.Navigation("Project"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", "Phase") + .WithMany("Tasks") + .HasForeignKey("PhaseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Phase"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.HasOne("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", "Skill") + .WithMany("Sections") + .HasForeignKey("SkillId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", "Task") + .WithMany("Sections") + .HasForeignKey("TaskId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Skill"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSectionActivity", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", "Section") + .WithMany("Activities") + .HasForeignKey("SectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Section"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSectionAdditionalTime", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", null) + .WithMany("AdditionalTimes") + .HasForeignKey("TaskSectionId"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.RoleAgg.Entities.Role", b => + { + b.OwnsMany("GozareshgirProgramManager.Domain.PermissionAgg.Entities.Permission", "Permissions", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("Code") + .HasColumnType("int"); + + b1.Property("RoleId") + .HasColumnType("bigint"); + + b1.HasKey("Id"); + + b1.HasIndex("RoleId"); + + b1.ToTable("RolePermissions", (string)null); + + b1.WithOwner("Role") + .HasForeignKey("RoleId"); + + b1.Navigation("Role"); + }); + + b.Navigation("Permissions"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities.SalaryPaymentSetting", b => + { + b.OwnsMany("GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities.WorkingHours", "WorkingHoursList", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("EndShiftOne") + .HasColumnType("time(0)"); + + b1.Property("EndShiftTwo") + .HasColumnType("time(0)"); + + b1.Property("HasRestTime") + .HasColumnType("bit"); + + b1.Property("HasShiftOne") + .HasColumnType("bit"); + + b1.Property("HasShiftTow") + .HasColumnType("bit"); + + b1.Property("IsActiveDay") + .HasColumnType("bit"); + + b1.Property("PersianDayOfWeek") + .HasColumnType("int"); + + b1.Property("RestTime") + .HasColumnType("time(0)"); + + b1.Property("SalaryPaymentSettingId") + .HasColumnType("bigint"); + + b1.Property("ShiftDurationInMinutes") + .HasColumnType("int"); + + b1.Property("StartShiftOne") + .HasColumnType("time(0)"); + + b1.Property("StartShiftTwo") + .HasColumnType("time(0)"); + + b1.HasKey("Id"); + + b1.HasIndex("SalaryPaymentSettingId"); + + b1.ToTable("WorkingHours", (string)null); + + b1.WithOwner("SalaryPaymentSetting") + .HasForeignKey("SalaryPaymentSettingId"); + + b1.Navigation("SalaryPaymentSetting"); + }); + + b.Navigation("WorkingHoursList"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b => + { + b.OwnsMany("GozareshgirProgramManager.Domain.RoleUserAgg.RoleUser", "RoleUser", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("RoleId") + .HasColumnType("bigint"); + + b1.Property("UserId") + .HasColumnType("bigint"); + + b1.HasKey("Id"); + + b1.HasIndex("UserId"); + + b1.ToTable("RoleUsers", (string)null); + + b1.WithOwner("User") + .HasForeignKey("UserId"); + + b1.Navigation("User"); + }); + + b.Navigation("RoleUser"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.UserRefreshToken", b => + { + b.HasOne("GozareshgirProgramManager.Domain.UserAgg.Entities.User", "User") + .WithMany("RefreshTokens") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project", b => + { + b.Navigation("Phases"); + + b.Navigation("ProjectSections"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", b => + { + b.Navigation("PhaseSections"); + + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", b => + { + b.Navigation("Sections"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.Navigation("Activities"); + + b.Navigation("AdditionalTimes"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", b => + { + b.Navigation("Sections"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b => + { + b.Navigation("RefreshTokens"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251206064818_add phase section and task section.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251206064818_add phase section and task section.cs new file mode 100644 index 00000000..889ac9de --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251206064818_add phase section and task section.cs @@ -0,0 +1,138 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace GozareshgirProgramManager.Infrastructure.Migrations +{ + /// + public partial class addphasesectionandtasksection : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_PhaseSection_ProjectPhases_PhaseId", + table: "PhaseSection"); + + migrationBuilder.DropForeignKey( + name: "FK_ProjectSection_Projects_ProjectId", + table: "ProjectSection"); + + migrationBuilder.DropPrimaryKey( + name: "PK_ProjectSection", + table: "ProjectSection"); + + migrationBuilder.DropPrimaryKey( + name: "PK_PhaseSection", + table: "PhaseSection"); + + migrationBuilder.RenameTable( + name: "ProjectSection", + newName: "ProjectSections"); + + migrationBuilder.RenameTable( + name: "PhaseSection", + newName: "PhaseSections"); + + migrationBuilder.RenameIndex( + name: "IX_ProjectSection_ProjectId", + table: "ProjectSections", + newName: "IX_ProjectSections_ProjectId"); + + migrationBuilder.RenameIndex( + name: "IX_PhaseSection_PhaseId", + table: "PhaseSections", + newName: "IX_PhaseSections_PhaseId"); + + migrationBuilder.AddPrimaryKey( + name: "PK_ProjectSections", + table: "ProjectSections", + column: "Id"); + + migrationBuilder.AddPrimaryKey( + name: "PK_PhaseSections", + table: "PhaseSections", + column: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_PhaseSections_ProjectPhases_PhaseId", + table: "PhaseSections", + column: "PhaseId", + principalTable: "ProjectPhases", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_ProjectSections_Projects_ProjectId", + table: "ProjectSections", + column: "ProjectId", + principalTable: "Projects", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_PhaseSections_ProjectPhases_PhaseId", + table: "PhaseSections"); + + migrationBuilder.DropForeignKey( + name: "FK_ProjectSections_Projects_ProjectId", + table: "ProjectSections"); + + migrationBuilder.DropPrimaryKey( + name: "PK_ProjectSections", + table: "ProjectSections"); + + migrationBuilder.DropPrimaryKey( + name: "PK_PhaseSections", + table: "PhaseSections"); + + migrationBuilder.RenameTable( + name: "ProjectSections", + newName: "ProjectSection"); + + migrationBuilder.RenameTable( + name: "PhaseSections", + newName: "PhaseSection"); + + migrationBuilder.RenameIndex( + name: "IX_ProjectSections_ProjectId", + table: "ProjectSection", + newName: "IX_ProjectSection_ProjectId"); + + migrationBuilder.RenameIndex( + name: "IX_PhaseSections_PhaseId", + table: "PhaseSection", + newName: "IX_PhaseSection_PhaseId"); + + migrationBuilder.AddPrimaryKey( + name: "PK_ProjectSection", + table: "ProjectSection", + column: "Id"); + + migrationBuilder.AddPrimaryKey( + name: "PK_PhaseSection", + table: "PhaseSection", + column: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_PhaseSection_ProjectPhases_PhaseId", + table: "PhaseSection", + column: "PhaseId", + principalTable: "ProjectPhases", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_ProjectSection_Projects_ProjectId", + table: "ProjectSection", + column: "ProjectId", + principalTable: "Projects", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251207080830_RoleAndRolePermissionTablerenamed.Designer.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251207080830_RoleAndRolePermissionTablerenamed.Designer.cs new file mode 100644 index 00000000..c7e4fc0a --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251207080830_RoleAndRolePermissionTablerenamed.Designer.cs @@ -0,0 +1,905 @@ +// +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("20251207080830_RoleAndRolePermissionTablerenamed")] + partial class RoleAndRolePermissionTablerenamed + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.CheckoutAgg.Entities.Checkout", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CheckoutEndDate") + .HasColumnType("datetime2"); + + b.Property("CheckoutStartDate") + .HasColumnType("datetime2"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("DeductionFromSalary") + .HasColumnType("float"); + + b.Property("FullName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("MandatoryHours") + .HasColumnType("int"); + + b.Property("Month") + .HasColumnType("int"); + + b.Property("MonthlySalaryDefined") + .HasColumnType("float"); + + b.Property("MonthlySalaryPay") + .HasColumnType("float"); + + b.Property("RemainingHours") + .HasColumnType("int"); + + b.Property("TotalDaysWorked") + .HasColumnType("int"); + + b.Property("TotalHoursWorked") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.Property("Year") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Checkouts", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.CustomerAgg.Customer", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("Customers", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.HolidayAgg.Holiday", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Year") + .IsRequired() + .HasMaxLength(4) + .HasColumnType("nvarchar(4)"); + + b.HasKey("Id"); + + b.ToTable("Holidays", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.HolidayItemAgg.HolidayItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("HolidayId") + .HasColumnType("bigint"); + + b.Property("HolidayYear") + .IsRequired() + .HasMaxLength(4) + .HasColumnType("nvarchar(4)"); + + b.Property("Holidaydate") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.HasIndex("HolidayId"); + + b.ToTable("Holidayitems", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.PhaseSection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("PhaseId") + .HasColumnType("uniqueidentifier"); + + b.Property("SkillId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("PhaseId"); + + b.ToTable("PhaseSections"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("HasAssignmentOverride") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("PlannedEndDate") + .HasColumnType("datetime2"); + + b.Property("PlannedStartDate") + .HasColumnType("datetime2"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.ToTable("Projects", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("HasAssignmentOverride") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("OrderIndex") + .HasColumnType("int"); + + b.Property("ProjectId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.ToTable("ProjectPhases", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSection", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("ProjectId") + .HasColumnType("uniqueidentifier"); + + b.Property("SkillId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.ToTable("ProjectSections"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AllocatedTime") + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("DueDate") + .HasColumnType("datetime2"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("HasAssignmentOverride") + .HasColumnType("bit"); + + b.Property("HasTimeOverride") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("OrderIndex") + .HasColumnType("int"); + + b.Property("PhaseId") + .HasColumnType("uniqueidentifier"); + + b.Property("Priority") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.HasIndex("PhaseId"); + + b.ToTable("ProjectTasks", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("CurrentAssignedUserId") + .HasColumnType("bigint"); + + b.Property("InitialDescription") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("InitialEstimatedHours") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("OriginalAssignedUserId") + .HasColumnType("bigint"); + + b.Property("SkillId") + .HasColumnType("uniqueidentifier"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("TaskId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("SkillId"); + + b.HasIndex("TaskId"); + + b.ToTable("TaskSections", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSectionActivity", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("EndNotes") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("Notes") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("SectionId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("SectionId"); + + b.ToTable("TaskSectionActivities", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSectionAdditionalTime", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AddedAt") + .HasColumnType("datetime2"); + + b.Property("AddedByUserId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Hours") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("Reason") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("TaskSectionId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("TaskSectionId"); + + b.ToTable("TaskSectionAdditionalTimes", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.RoleAgg.Entities.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("GozareshgirRoleId") + .HasColumnType("bigint"); + + b.Property("RoleName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.HasKey("Id"); + + b.ToTable("PmRoles", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities.SalaryPaymentSetting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("EndSettingDate") + .HasColumnType("datetime2"); + + b.Property("HolidayWorking") + .HasColumnType("bit"); + + b.Property("MonthlySalary") + .HasColumnType("float"); + + b.Property("StartSettingDate") + .HasColumnType("datetime2"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.ToTable("SalaryPaymentSetting", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("Skills", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .HasMaxLength(150) + .HasColumnType("nvarchar(150)"); + + b.Property("FullName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("Mobile") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.Property("Password") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("ProfilePhotoPath") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("VerifyCode") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.HasKey("Id"); + + b.ToTable("Users", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.UserRefreshToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("ExpiresAt") + .HasColumnType("datetime2"); + + b.Property("IpAddress") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("RevokedAt") + .HasColumnType("datetime2"); + + b.Property("Token") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UserAgent") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("ExpiresAt"); + + b.HasIndex("Token") + .IsUnique(); + + b.HasIndex("UserId"); + + b.ToTable("UserRefreshTokens", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.HolidayItemAgg.HolidayItem", b => + { + b.HasOne("GozareshgirProgramManager.Domain.HolidayAgg.Holiday", "Holidayss") + .WithMany("HolidayItems") + .HasForeignKey("HolidayId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Holidayss"); + }); + + 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.Navigation("Phase"); + }); + + 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.Navigation("Project"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", "Phase") + .WithMany("Tasks") + .HasForeignKey("PhaseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Phase"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.HasOne("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", "Skill") + .WithMany("Sections") + .HasForeignKey("SkillId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", "Task") + .WithMany("Sections") + .HasForeignKey("TaskId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Skill"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSectionActivity", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", "Section") + .WithMany("Activities") + .HasForeignKey("SectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Section"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSectionAdditionalTime", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", null) + .WithMany("AdditionalTimes") + .HasForeignKey("TaskSectionId"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.RoleAgg.Entities.Role", b => + { + b.OwnsMany("GozareshgirProgramManager.Domain.PermissionAgg.Entities.Permission", "Permissions", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("Code") + .HasColumnType("int"); + + b1.Property("RoleId") + .HasColumnType("bigint"); + + b1.HasKey("Id"); + + b1.HasIndex("RoleId"); + + b1.ToTable("PmRolePermissions", (string)null); + + b1.WithOwner("Role") + .HasForeignKey("RoleId"); + + b1.Navigation("Role"); + }); + + b.Navigation("Permissions"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities.SalaryPaymentSetting", b => + { + b.OwnsMany("GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities.WorkingHours", "WorkingHoursList", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("EndShiftOne") + .HasColumnType("time(0)"); + + b1.Property("EndShiftTwo") + .HasColumnType("time(0)"); + + b1.Property("HasRestTime") + .HasColumnType("bit"); + + b1.Property("HasShiftOne") + .HasColumnType("bit"); + + b1.Property("HasShiftTow") + .HasColumnType("bit"); + + b1.Property("IsActiveDay") + .HasColumnType("bit"); + + b1.Property("PersianDayOfWeek") + .HasColumnType("int"); + + b1.Property("RestTime") + .HasColumnType("time(0)"); + + b1.Property("SalaryPaymentSettingId") + .HasColumnType("bigint"); + + b1.Property("ShiftDurationInMinutes") + .HasColumnType("int"); + + b1.Property("StartShiftOne") + .HasColumnType("time(0)"); + + b1.Property("StartShiftTwo") + .HasColumnType("time(0)"); + + b1.HasKey("Id"); + + b1.HasIndex("SalaryPaymentSettingId"); + + b1.ToTable("WorkingHours", (string)null); + + b1.WithOwner("SalaryPaymentSetting") + .HasForeignKey("SalaryPaymentSettingId"); + + b1.Navigation("SalaryPaymentSetting"); + }); + + b.Navigation("WorkingHoursList"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b => + { + b.OwnsMany("GozareshgirProgramManager.Domain.RoleUserAgg.RoleUser", "RoleUser", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("RoleId") + .HasColumnType("bigint"); + + b1.Property("UserId") + .HasColumnType("bigint"); + + b1.HasKey("Id"); + + b1.HasIndex("UserId"); + + b1.ToTable("RoleUsers", (string)null); + + b1.WithOwner("User") + .HasForeignKey("UserId"); + + b1.Navigation("User"); + }); + + b.Navigation("RoleUser"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.UserRefreshToken", b => + { + b.HasOne("GozareshgirProgramManager.Domain.UserAgg.Entities.User", "User") + .WithMany("RefreshTokens") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.HolidayAgg.Holiday", b => + { + b.Navigation("HolidayItems"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project", b => + { + b.Navigation("Phases"); + + b.Navigation("ProjectSections"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", b => + { + b.Navigation("PhaseSections"); + + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", b => + { + b.Navigation("Sections"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.Navigation("Activities"); + + b.Navigation("AdditionalTimes"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", b => + { + b.Navigation("Sections"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b => + { + b.Navigation("RefreshTokens"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251207080830_RoleAndRolePermissionTablerenamed.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251207080830_RoleAndRolePermissionTablerenamed.cs new file mode 100644 index 00000000..4b02748e --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251207080830_RoleAndRolePermissionTablerenamed.cs @@ -0,0 +1,109 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace GozareshgirProgramManager.Infrastructure.Migrations +{ + /// + public partial class RoleAndRolePermissionTablerenamed : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "RolePermissions"); + + migrationBuilder.DropPrimaryKey( + name: "PK_Roles", + table: "Roles"); + + migrationBuilder.RenameTable( + name: "Roles", + newName: "PmRoles"); + + migrationBuilder.AddPrimaryKey( + name: "PK_PmRoles", + table: "PmRoles", + column: "Id"); + + + + migrationBuilder.CreateTable( + name: "PmRolePermissions", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Code = table.Column(type: "int", nullable: false), + RoleId = table.Column(type: "bigint", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_PmRolePermissions", x => x.Id); + table.ForeignKey( + name: "FK_PmRolePermissions_PmRoles_RoleId", + column: x => x.RoleId, + principalTable: "PmRoles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + + + migrationBuilder.CreateIndex( + name: "IX_PmRolePermissions_RoleId", + table: "PmRolePermissions", + column: "RoleId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + + + migrationBuilder.DropTable( + name: "PmRolePermissions"); + + + + migrationBuilder.DropPrimaryKey( + name: "PK_PmRoles", + table: "PmRoles"); + + migrationBuilder.RenameTable( + name: "PmRoles", + newName: "Roles"); + + migrationBuilder.AddPrimaryKey( + name: "PK_Roles", + table: "Roles", + column: "Id"); + + migrationBuilder.CreateTable( + name: "RolePermissions", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + RoleId = table.Column(type: "bigint", nullable: false), + Code = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_RolePermissions", x => x.Id); + table.ForeignKey( + name: "FK_RolePermissions_Roles_RoleId", + column: x => x.RoleId, + principalTable: "Roles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_RolePermissions_RoleId", + table: "RolePermissions", + column: "RoleId"); + } + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/AppDbContextModelSnapshot.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/AppDbContextModelSnapshot.cs new file mode 100644 index 00000000..8e4c3871 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/AppDbContextModelSnapshot.cs @@ -0,0 +1,902 @@ +// +using System; +using GozareshgirProgramManager.Infrastructure.Persistence.Context; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace GozareshgirProgramManager.Infrastructure.Migrations +{ + [DbContext(typeof(ProgramManagerDbContext))] + partial class AppDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.CheckoutAgg.Entities.Checkout", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CheckoutEndDate") + .HasColumnType("datetime2"); + + b.Property("CheckoutStartDate") + .HasColumnType("datetime2"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("DeductionFromSalary") + .HasColumnType("float"); + + b.Property("FullName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("MandatoryHours") + .HasColumnType("int"); + + b.Property("Month") + .HasColumnType("int"); + + b.Property("MonthlySalaryDefined") + .HasColumnType("float"); + + b.Property("MonthlySalaryPay") + .HasColumnType("float"); + + b.Property("RemainingHours") + .HasColumnType("int"); + + b.Property("TotalDaysWorked") + .HasColumnType("int"); + + b.Property("TotalHoursWorked") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.Property("Year") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Checkouts", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.CustomerAgg.Customer", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("Customers", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.HolidayAgg.Holiday", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Year") + .IsRequired() + .HasMaxLength(4) + .HasColumnType("nvarchar(4)"); + + b.HasKey("Id"); + + b.ToTable("Holidays", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.HolidayItemAgg.HolidayItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("HolidayId") + .HasColumnType("bigint"); + + b.Property("HolidayYear") + .IsRequired() + .HasMaxLength(4) + .HasColumnType("nvarchar(4)"); + + b.Property("Holidaydate") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.HasIndex("HolidayId"); + + b.ToTable("Holidayitems", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.PhaseSection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("PhaseId") + .HasColumnType("uniqueidentifier"); + + b.Property("SkillId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("PhaseId"); + + b.ToTable("PhaseSections"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("HasAssignmentOverride") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("PlannedEndDate") + .HasColumnType("datetime2"); + + b.Property("PlannedStartDate") + .HasColumnType("datetime2"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.ToTable("Projects", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("HasAssignmentOverride") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("OrderIndex") + .HasColumnType("int"); + + b.Property("ProjectId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.ToTable("ProjectPhases", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSection", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("ProjectId") + .HasColumnType("uniqueidentifier"); + + b.Property("SkillId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.ToTable("ProjectSections"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AllocatedTime") + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("DueDate") + .HasColumnType("datetime2"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("HasAssignmentOverride") + .HasColumnType("bit"); + + b.Property("HasTimeOverride") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("OrderIndex") + .HasColumnType("int"); + + b.Property("PhaseId") + .HasColumnType("uniqueidentifier"); + + b.Property("Priority") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.HasIndex("PhaseId"); + + b.ToTable("ProjectTasks", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("CurrentAssignedUserId") + .HasColumnType("bigint"); + + b.Property("InitialDescription") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("InitialEstimatedHours") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("OriginalAssignedUserId") + .HasColumnType("bigint"); + + b.Property("SkillId") + .HasColumnType("uniqueidentifier"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("TaskId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("SkillId"); + + b.HasIndex("TaskId"); + + b.ToTable("TaskSections", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSectionActivity", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("EndNotes") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("Notes") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("SectionId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("SectionId"); + + b.ToTable("TaskSectionActivities", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSectionAdditionalTime", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AddedAt") + .HasColumnType("datetime2"); + + b.Property("AddedByUserId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Hours") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("Reason") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("TaskSectionId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("TaskSectionId"); + + b.ToTable("TaskSectionAdditionalTimes", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.RoleAgg.Entities.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("GozareshgirRoleId") + .HasColumnType("bigint"); + + b.Property("RoleName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.HasKey("Id"); + + b.ToTable("PmRoles", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities.SalaryPaymentSetting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("EndSettingDate") + .HasColumnType("datetime2"); + + b.Property("HolidayWorking") + .HasColumnType("bit"); + + b.Property("MonthlySalary") + .HasColumnType("float"); + + b.Property("StartSettingDate") + .HasColumnType("datetime2"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.ToTable("SalaryPaymentSetting", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("Skills", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .HasMaxLength(150) + .HasColumnType("nvarchar(150)"); + + b.Property("FullName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("Mobile") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.Property("Password") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("ProfilePhotoPath") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("VerifyCode") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.HasKey("Id"); + + b.ToTable("Users", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.UserRefreshToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("ExpiresAt") + .HasColumnType("datetime2"); + + b.Property("IpAddress") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("RevokedAt") + .HasColumnType("datetime2"); + + b.Property("Token") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UserAgent") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("ExpiresAt"); + + b.HasIndex("Token") + .IsUnique(); + + b.HasIndex("UserId"); + + b.ToTable("UserRefreshTokens", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.HolidayItemAgg.HolidayItem", b => + { + b.HasOne("GozareshgirProgramManager.Domain.HolidayAgg.Holiday", "Holidayss") + .WithMany("HolidayItems") + .HasForeignKey("HolidayId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Holidayss"); + }); + + 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.Navigation("Phase"); + }); + + 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.Navigation("Project"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", "Phase") + .WithMany("Tasks") + .HasForeignKey("PhaseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Phase"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.HasOne("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", "Skill") + .WithMany("Sections") + .HasForeignKey("SkillId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", "Task") + .WithMany("Sections") + .HasForeignKey("TaskId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Skill"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSectionActivity", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", "Section") + .WithMany("Activities") + .HasForeignKey("SectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Section"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSectionAdditionalTime", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", null) + .WithMany("AdditionalTimes") + .HasForeignKey("TaskSectionId"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.RoleAgg.Entities.Role", b => + { + b.OwnsMany("GozareshgirProgramManager.Domain.PermissionAgg.Entities.Permission", "Permissions", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("Code") + .HasColumnType("int"); + + b1.Property("RoleId") + .HasColumnType("bigint"); + + b1.HasKey("Id"); + + b1.HasIndex("RoleId"); + + b1.ToTable("PmRolePermissions", (string)null); + + b1.WithOwner("Role") + .HasForeignKey("RoleId"); + + b1.Navigation("Role"); + }); + + b.Navigation("Permissions"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities.SalaryPaymentSetting", b => + { + b.OwnsMany("GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities.WorkingHours", "WorkingHoursList", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("EndShiftOne") + .HasColumnType("time(0)"); + + b1.Property("EndShiftTwo") + .HasColumnType("time(0)"); + + b1.Property("HasRestTime") + .HasColumnType("bit"); + + b1.Property("HasShiftOne") + .HasColumnType("bit"); + + b1.Property("HasShiftTow") + .HasColumnType("bit"); + + b1.Property("IsActiveDay") + .HasColumnType("bit"); + + b1.Property("PersianDayOfWeek") + .HasColumnType("int"); + + b1.Property("RestTime") + .HasColumnType("time(0)"); + + b1.Property("SalaryPaymentSettingId") + .HasColumnType("bigint"); + + b1.Property("ShiftDurationInMinutes") + .HasColumnType("int"); + + b1.Property("StartShiftOne") + .HasColumnType("time(0)"); + + b1.Property("StartShiftTwo") + .HasColumnType("time(0)"); + + b1.HasKey("Id"); + + b1.HasIndex("SalaryPaymentSettingId"); + + b1.ToTable("WorkingHours", (string)null); + + b1.WithOwner("SalaryPaymentSetting") + .HasForeignKey("SalaryPaymentSettingId"); + + b1.Navigation("SalaryPaymentSetting"); + }); + + b.Navigation("WorkingHoursList"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b => + { + b.OwnsMany("GozareshgirProgramManager.Domain.RoleUserAgg.RoleUser", "RoleUser", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("RoleId") + .HasColumnType("bigint"); + + b1.Property("UserId") + .HasColumnType("bigint"); + + b1.HasKey("Id"); + + b1.HasIndex("UserId"); + + b1.ToTable("RoleUsers", (string)null); + + b1.WithOwner("User") + .HasForeignKey("UserId"); + + b1.Navigation("User"); + }); + + b.Navigation("RoleUser"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.UserRefreshToken", b => + { + b.HasOne("GozareshgirProgramManager.Domain.UserAgg.Entities.User", "User") + .WithMany("RefreshTokens") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.HolidayAgg.Holiday", b => + { + b.Navigation("HolidayItems"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project", b => + { + b.Navigation("Phases"); + + b.Navigation("ProjectSections"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", b => + { + b.Navigation("PhaseSections"); + + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", b => + { + b.Navigation("Sections"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.Navigation("Activities"); + + b.Navigation("AdditionalTimes"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", b => + { + b.Navigation("Sections"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b => + { + b.Navigation("RefreshTokens"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Context/ProgramManagerDbContext.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Context/ProgramManagerDbContext.cs new file mode 100644 index 00000000..2fc4854c --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Context/ProgramManagerDbContext.cs @@ -0,0 +1,61 @@ +using GozareshgirProgramManager.Application._Common.Interfaces; + using GozareshgirProgramManager.Domain.CheckoutAgg.Entities; + using GozareshgirProgramManager.Domain.CustomerAgg; +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Domain.CustomerAgg; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.RoleAgg.Entities; +using GozareshgirProgramManager.Domain.RoleUserAgg; +using GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities; +using GozareshgirProgramManager.Domain.UserAgg.Entities; +using GozareshgirProgramManager.Domain.SkillAgg.Entities; +using Microsoft.EntityFrameworkCore; + +namespace GozareshgirProgramManager.Infrastructure.Persistence.Context; + +public class ProgramManagerDbContext : DbContext, IProgramManagerDbContext +{ + public ProgramManagerDbContext(DbContextOptions options) : base(options) + { + } + + public DbSet Customers { get; set; } = null!; + public DbSet TaskSections { get; set; } = null!; + public DbSet ProjectSections { get; set; } = null!; + public DbSet PhaseSections { get; set; } = null!; + + // New Hierarchy entities + public DbSet Projects { get; set; } = null!; + public DbSet ProjectPhases { get; set; } = null!; + public DbSet ProjectTasks { get; set; } = null!; + + public DbSet TaskSectionActivities { get; set; } = null!; + public DbSet TaskSectionAdditionalTimes { get; set; } = null!; + + public DbSet Users { get; set; } = null!; + public DbSet RefreshTokens { get; set; } = null!; + + public DbSet Checkouts { get; set; } = null!; + public DbSet SalaryPaymentSettings { get; set; } = null!; + public DbSet Roles { get; set; } = null!; + + public DbSet Skills { get; set; } = null!; + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.ApplyConfigurationsFromAssembly(typeof(ProgramManagerDbContext).Assembly); + base.OnModelCreating(modelBuilder); + } + + public async Task SeedSkillsIfEmptyAsync() + { + if (!Skills.Any()) + { + Skills.AddRange( + new Skill("UI/UX Design"), + new Skill("Frontend"), + new Skill("Backend") + ); + await SaveChangesAsync(); + } + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/AdditionalTimeMapping.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/AdditionalTimeMapping.cs new file mode 100644 index 00000000..6c73bc87 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/AdditionalTimeMapping.cs @@ -0,0 +1,23 @@ +using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Infrastructure.Persistence._Common; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace GozareshgirProgramManager.Infrastructure.Persistence.Mappings; + +public class AdditionalTimeMapping:IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("AdditionalTimes"); + + builder.HasKey(ts => ts.Id); + + builder.Property(ts => ts.Id) + .ValueGeneratedNever(); + + builder.Property(x => x.Reason).HasMaxLength(1000); + + builder.Property(x => x.Hours).HasTimeSpanConversion(); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/CheckoutMapping.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/CheckoutMapping.cs new file mode 100644 index 00000000..3c8d83f8 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/CheckoutMapping.cs @@ -0,0 +1,19 @@ +using GozareshgirProgramManager.Domain.CheckoutAgg.Entities; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace GozareshgirProgramManager.Infrastructure.Persistence.Mappings; + +public class CheckoutMapping : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("Checkouts"); + builder.HasKey(s => s.Id); + + builder.Property(s => s.Id) + .ValueGeneratedNever(); + + builder.Property(x => x.FullName).HasMaxLength(100); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/CustomerMapping.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/CustomerMapping.cs new file mode 100644 index 00000000..e40e9b14 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/CustomerMapping.cs @@ -0,0 +1,29 @@ +using GozareshgirProgramManager.Domain.CustomerAgg; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace GozareshgirProgramManager.Infrastructure.Persistence.Mappings; + +public class CustomerMapping : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("Customers"); + + builder.HasKey(c => c.Id); + + builder.Property(c => c.Id) + .ValueGeneratedNever(); + + builder.Property(c => c.Name) + .IsRequired() + .HasMaxLength(200); + + builder.Property(c => c.Email) + .IsRequired() + .HasMaxLength(256); + + builder.Property(c => c.CreatedAt) + .IsRequired(); + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/HolidayItemMapping.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/HolidayItemMapping.cs new file mode 100644 index 00000000..42eff124 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/HolidayItemMapping.cs @@ -0,0 +1,20 @@ +using GozareshgirProgramManager.Domain.HolidayItemAgg; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace GozareshgirProgramManager.Infrastructure.Persistence.Mappings; + +public class HolidayItemMapping : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("Holidayitems"); + builder.HasKey(x => x.Id); + + builder.Property(x => x.HolidayYear).HasMaxLength(4); + + builder.HasOne(x => x.Holidayss) + .WithMany(x => x.HolidayItems) + .HasForeignKey(x => x.HolidayId); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/HolidayMapping.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/HolidayMapping.cs new file mode 100644 index 00000000..3038d89a --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/HolidayMapping.cs @@ -0,0 +1,20 @@ +using GozareshgirProgramManager.Domain.HolidayAgg; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace GozareshgirProgramManager.Infrastructure.Persistence.Mappings; + +public class HolidayMapping : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("Holidays"); + builder.HasKey(x => x.Id); + + builder.Property(x => x.Year).HasMaxLength(4); + + builder.HasMany(x => x.HolidayItems) + .WithOne(x => x.Holidayss) + .HasForeignKey(x => x.HolidayId); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/PhaseSectionMapping.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/PhaseSectionMapping.cs new file mode 100644 index 00000000..c1db7d49 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/PhaseSectionMapping.cs @@ -0,0 +1,21 @@ +using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace GozareshgirProgramManager.Infrastructure.Persistence.Mappings; + +public class PhaseSectionMapping:IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.HasKey(ps => ps.Id); + + builder.Property(ps => ps.Id) + .ValueGeneratedOnAdd(); + + builder.HasOne(ps => ps.Phase) + .WithMany(p => p.PhaseSections) + .HasForeignKey(ps => ps.PhaseId) + .OnDelete(DeleteBehavior.Cascade); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/ProjectMapping.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/ProjectMapping.cs new file mode 100644 index 00000000..69a79750 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/ProjectMapping.cs @@ -0,0 +1,58 @@ +using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Enums; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace GozareshgirProgramManager.Infrastructure.Persistence.Mappings; + +public class ProjectMapping : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("Projects"); + + builder.HasKey(p => p.Id); + + builder.Property(p => p.Id) + .ValueGeneratedNever(); + + builder.Property(p => p.Name) + .HasMaxLength(200) + .IsRequired(); + + builder.Property(p => p.Description) + .HasMaxLength(1000) + .IsRequired(false); + + builder.Property(p => p.CreationDate) + .IsRequired(); + + builder.Property(p => p.StartDate) + .IsRequired(false); + + builder.Property(p => p.EndDate) + .IsRequired(false); + + builder.Property(p => p.PlannedStartDate) + .IsRequired(false); + + builder.Property(p => p.PlannedEndDate) + .IsRequired(false); + + builder.Property(p => p.Status) + .HasConversion() + .HasMaxLength(50) + .IsRequired(); + + builder.Property(p => p.HasAssignmentOverride) + .IsRequired(); + + // One-to-many relationship with ProjectPhases + builder.HasMany(p => p.Phases) + .WithOne(ph => ph.Project) + .HasForeignKey(ph => ph.ProjectId) + .OnDelete(DeleteBehavior.Cascade); + + + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/ProjectPhaseMapping.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/ProjectPhaseMapping.cs new file mode 100644 index 00000000..838b7f0e --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/ProjectPhaseMapping.cs @@ -0,0 +1,64 @@ +using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Enums; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace GozareshgirProgramManager.Infrastructure.Persistence.Mappings; + +public class ProjectPhaseMapping : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("ProjectPhases"); + + builder.HasKey(ph => ph.Id); + + builder.Property(ph => ph.Id) + .ValueGeneratedNever(); + + builder.Property(ph => ph.Name) + .HasMaxLength(200) + .IsRequired(); + + builder.Property(ph => ph.Description) + .HasMaxLength(1000) + .IsRequired(false); + + builder.Property(ph => ph.CreationDate) + .IsRequired(); + + builder.Property(ph => ph.ProjectId) + .IsRequired(); + + builder.Property(ph => ph.Status) + .HasConversion() + .HasMaxLength(50) + .IsRequired(); + + builder.Property(ph => ph.StartDate) + .IsRequired(false); + + builder.Property(ph => ph.EndDate) + .IsRequired(false); + + builder.Property(ph => ph.OrderIndex) + .IsRequired(); + + + builder.Property(ph => ph.HasAssignmentOverride) + .IsRequired(); + + // Relationship with Project + builder.HasOne(ph => ph.Project) + .WithMany(p => p.Phases) + .HasForeignKey(ph => ph.ProjectId) + .OnDelete(DeleteBehavior.Cascade); + + // One-to-many relationship with ProjectTasks + builder.HasMany(ph => ph.Tasks) + .WithOne(t => t.Phase) + .HasForeignKey(t => t.PhaseId) + .OnDelete(DeleteBehavior.Cascade); + + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/ProjectSectionMapping.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/ProjectSectionMapping.cs new file mode 100644 index 00000000..ebc8df44 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/ProjectSectionMapping.cs @@ -0,0 +1,20 @@ +using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace GozareshgirProgramManager.Infrastructure.Persistence.Mappings; + +public class ProjectSectionMapping:IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.HasKey(x => x.Id); + builder.Property(x => x.Id) + .ValueGeneratedNever(); + + builder.HasOne(x => x.Project) + .WithMany(x => x.ProjectSections) + .HasForeignKey(x => x.ProjectId) + .OnDelete(DeleteBehavior.Cascade); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/ProjectTaskMapping.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/ProjectTaskMapping.cs new file mode 100644 index 00000000..705af3d6 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/ProjectTaskMapping.cs @@ -0,0 +1,79 @@ +using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Enums; +using GozareshgirProgramManager.Infrastructure.Persistence._Common; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace GozareshgirProgramManager.Infrastructure.Persistence.Mappings; + +public class ProjectTaskMapping : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("ProjectTasks"); + + builder.HasKey(t => t.Id); + + builder.Property(t => t.Id) + .ValueGeneratedNever(); + + builder.Property(t => t.Name) + .HasMaxLength(200) + .IsRequired(); + + builder.Property(t => t.Description) + .HasMaxLength(1000) + .IsRequired(false); + + builder.Property(t => t.CreationDate) + .IsRequired(); + + builder.Property(t => t.PhaseId) + .IsRequired(); + + builder.Property(t => t.Status) + .HasConversion() + .HasMaxLength(50) + .IsRequired(); + + builder.Property(t => t.Priority) + .HasConversion() + .HasMaxLength(50) + .IsRequired(); + + builder.Property(t => t.StartDate) + .IsRequired(false); + + builder.Property(t => t.EndDate) + .IsRequired(false); + + builder.Property(t => t.DueDate) + .IsRequired(false); + + builder.Property(t => t.OrderIndex) + .IsRequired(); + + builder.Property(t => t.AllocatedTime) + .HasTimeSpanConversion() + .IsRequired(false); + + builder.Property(t => t.HasTimeOverride) + .IsRequired(); + + builder.Property(t => t.HasAssignmentOverride) + .IsRequired(); + + // Relationship with ProjectPhase + builder.HasOne(t => t.Phase) + .WithMany(ph => ph.Tasks) + .HasForeignKey(t => t.PhaseId) + .OnDelete(DeleteBehavior.Cascade); + + // One-to-many relationship with ProjectSections + builder.HasMany(t => t.Sections) + .WithOne(s => s.Task) + .HasForeignKey(s => s.TaskId) + .OnDelete(DeleteBehavior.Cascade); + + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/RefreshTokenMapping.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/RefreshTokenMapping.cs new file mode 100644 index 00000000..42ac6330 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/RefreshTokenMapping.cs @@ -0,0 +1,50 @@ +using GozareshgirProgramManager.Domain.UserAgg.Entities; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace GozareshgirProgramManager.Infrastructure.Persistence.Mappings; + +public class RefreshTokenMapping : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("UserRefreshTokens"); + builder.HasKey(x => x.Id); + + builder.Property(x => x.Token) + .HasMaxLength(500) + .IsRequired(); + + builder.Property(x => x.ExpiresAt) + .IsRequired(); + + builder.Property(x => x.RevokedAt) + .IsRequired(false); + + builder.Property(x => x.IpAddress) + .HasMaxLength(50) + .IsRequired(false); + + builder.Property(x => x.UserAgent) + .HasMaxLength(500) + .IsRequired(false); + + builder.Property(x => x.UserId) + .IsRequired(); + + // رابطه با User + builder.HasOne(x => x.User) + .WithMany(u => u.RefreshTokens) + .HasForeignKey(x => x.UserId) + .OnDelete(DeleteBehavior.Cascade); + + // Index برای بهینه‌سازی جستجو + builder.HasIndex(x => x.Token) + .IsUnique(); + + builder.HasIndex(x => x.UserId); + + builder.HasIndex(x => x.ExpiresAt); + } +} + diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/RoleMapping.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/RoleMapping.cs new file mode 100644 index 00000000..085a3d81 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/RoleMapping.cs @@ -0,0 +1,23 @@ +using GozareshgirProgramManager.Domain.RoleAgg.Entities; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace GozareshgirProgramManager.Infrastructure.Persistence.Mappings; + +public class RoleMapping : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("PmRoles"); + builder.HasKey(x => x.Id); + + builder.Property(x => x.RoleName).HasMaxLength(100).IsRequired(); + + builder.OwnsMany(x => x.Permissions, navigationBuilder => + { + navigationBuilder.HasKey(x => x.Id); + navigationBuilder.ToTable("PmRolePermissions"); + navigationBuilder.WithOwner(x => x.Role); + }); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/SalaryPaymentSettingMapping.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/SalaryPaymentSettingMapping.cs new file mode 100644 index 00000000..f6d69733 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/SalaryPaymentSettingMapping.cs @@ -0,0 +1,50 @@ +using GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities; +using GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Enums; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace GozareshgirProgramManager.Infrastructure.Persistence.Mappings; + +public class SalaryPaymentSettingMapping : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("SalaryPaymentSetting"); + builder.HasKey(x => x.Id); + + builder.Property(x => x.StartSettingDate).IsRequired(false); + builder.Property(x => x.EndSettingDate).IsRequired(false); + + builder.OwnsMany(x => x.WorkingHoursList, navigationBuilder => + { + navigationBuilder.HasKey(x => x.Id); + navigationBuilder.ToTable("WorkingHours"); + navigationBuilder.WithOwner(x => x.SalaryPaymentSetting); + + navigationBuilder.Property(x => x.StartShiftOne) + .HasColumnType("time(0)") + .IsRequired(true); + + navigationBuilder.Property(x => x.EndShiftOne) + .HasColumnType("time(0)") + .IsRequired(true); + + navigationBuilder.Property(x => x.StartShiftTwo) + .HasColumnType("time(0)") + .IsRequired(true); + + navigationBuilder.Property(x => x.EndShiftTwo) + .HasColumnType("time(0)") + .IsRequired(true); + + navigationBuilder.Property(x => x.RestTime) + .HasColumnType("time(0)") + .IsRequired(true); + + navigationBuilder + .Property(x => x.PersianDayOfWeek) + .HasConversion(); + + }); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/SkillMapping.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/SkillMapping.cs new file mode 100644 index 00000000..b142abe8 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/SkillMapping.cs @@ -0,0 +1,27 @@ +using GozareshgirProgramManager.Domain.SkillAgg.Entities; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace GozareshgirProgramManager.Infrastructure.Persistence.Mappings; + +public class SkillMapping:IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("Skills"); + + builder.HasKey(s => s.Id); + + builder.Property(s => s.Id) + .ValueGeneratedNever(); + + builder.Property(s => s.Name) + .IsRequired() + .HasMaxLength(200); + + builder.HasMany(x=>x.Sections) + .WithOne(x => x.Skill) + .HasForeignKey(f=>f.SkillId) + .OnDelete(DeleteBehavior.Cascade); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionActivityMapping.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionActivityMapping.cs new file mode 100644 index 00000000..84f4227e --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionActivityMapping.cs @@ -0,0 +1,53 @@ +using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace GozareshgirProgramManager.Infrastructure.Persistence.Mappings; + +public class TaskSectionActivityMapping : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("TaskSectionActivities"); + + builder.HasKey(a => a.Id); + + builder.Property(a => a.Id) + .ValueGeneratedNever(); + + builder.Property(a => a.SectionId) + .IsRequired(); + + builder.Property(a => a.UserId) + .IsRequired(); + + builder.Property(a => a.StartDate) + .IsRequired(); + + builder.Property(a => a.EndDate) + .IsRequired(false); + + builder.Property(a => a.Notes) + .HasMaxLength(1000) + .IsRequired(false); + + builder.Property(a => a.EndNotes) + .HasMaxLength(1000) + .IsRequired(false); + + builder.Property(a => a.IsActive) + .IsRequired(); + + builder.Property(a => a.CreationDate) + .IsRequired(); + + // Relationship with TaskSection + builder.HasOne(a => a.Section) + .WithMany(s => s.Activities) + .HasForeignKey(a => a.SectionId) + .OnDelete(DeleteBehavior.Cascade); + + // Ignore domain events + builder.Ignore(a => a.DomainEvents); + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionAdditionalTimeMapping.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionAdditionalTimeMapping.cs new file mode 100644 index 00000000..e6789d94 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionAdditionalTimeMapping.cs @@ -0,0 +1,39 @@ +using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Infrastructure.Persistence._Common; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace GozareshgirProgramManager.Infrastructure.Persistence.Mappings; + +public class TaskSectionAdditionalTimeMapping : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("TaskSectionAdditionalTimes"); + + builder.HasKey(at => at.Id); + + builder.Property(at => at.Id) + .ValueGeneratedNever(); + + builder.Property(at => at.Hours) + .HasTimeSpanConversion() + .IsRequired(); + + builder.Property(at => at.Reason) + .HasMaxLength(500) + .IsRequired(false); + + builder.Property(at => at.AddedByUserId) + .IsRequired(false); + + builder.Property(at => at.AddedAt) + .IsRequired(); + + builder.Property(at => at.CreationDate) + .IsRequired(); + + // Ignore domain events + builder.Ignore(at => at.DomainEvents); + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionMapping.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionMapping.cs new file mode 100644 index 00000000..836580f0 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/TaskSectionMapping.cs @@ -0,0 +1,53 @@ +using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Enums; +using GozareshgirProgramManager.Infrastructure.Persistence._Common; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace GozareshgirProgramManager.Infrastructure.Persistence.Mappings; + +public class TaskSectionMapping : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("TaskSections"); + + builder.HasKey(ts => ts.Id); + + builder.Property(ts => ts.Id) + .ValueGeneratedNever(); + + builder.Property(ts => ts.TaskId) + .IsRequired(); + + + builder.Property(ts => ts.InitialEstimatedHours) + .HasTimeSpanConversion(); + + builder.Property(ts => ts.Status) + .HasConversion() + .HasMaxLength(50) + .IsRequired(); + + builder.Property(x=>x.InitialDescription) + .HasMaxLength(500) + .IsRequired(false); + + builder.Property(ts => ts.CurrentAssignedUserId); + + // Navigation to ProjectTask (Task level) + builder.HasOne(ts => ts.Task) + .WithMany(t => t.Sections) + .HasForeignKey(ts => ts.TaskId) + .OnDelete(DeleteBehavior.Cascade); + + builder.HasMany(ts => ts.Activities) + .WithOne(a => a.Section) + .HasForeignKey(a => a.SectionId) + .OnDelete(DeleteBehavior.Cascade); + + builder.HasOne(x => x.Skill) + .WithMany(y => y.Sections).HasForeignKey(y => y.SkillId) + .OnDelete(DeleteBehavior.Cascade); + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/UserMapping.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/UserMapping.cs new file mode 100644 index 00000000..39ca99ac --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/UserMapping.cs @@ -0,0 +1,34 @@ +using GozareshgirProgramManager.Domain.UserAgg.Entities; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace GozareshgirProgramManager.Infrastructure.Persistence.Mappings; + +public class UserMapping :IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("Users"); + builder.HasKey(x => x.Id); + + builder.Property(x => x.FullName).HasMaxLength(100).IsRequired(); + builder.Property(x => x.UserName).HasMaxLength(100).IsRequired(); + builder.Property(x => x.Password).HasMaxLength(1000).IsRequired(); + builder.Property(x => x.ProfilePhotoPath).HasMaxLength(500).IsRequired(false); + builder.Property(x => x.Mobile).HasMaxLength(20).IsRequired(); + builder.Property(x => x.Email).HasMaxLength(150).IsRequired(false); ; + builder.Property(x => x.VerifyCode).HasMaxLength(10).IsRequired(false); + builder.OwnsMany(x => x.RoleUser, navigationBuilder => + { + navigationBuilder.HasKey(x => x.Id); + navigationBuilder.ToTable("RoleUsers"); + navigationBuilder.WithOwner(x => x.User); + }); + + builder.HasMany(x=>x.RefreshTokens) + .WithOne(x=>x.User) + .HasForeignKey(x=>x.UserId) + .OnDelete(DeleteBehavior.Cascade); + + } +} \ No newline at end of file diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/CheckoutRepository.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/CheckoutRepository.cs new file mode 100644 index 00000000..a34fcce7 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/CheckoutRepository.cs @@ -0,0 +1,22 @@ +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Domain.CheckoutAgg.Entities; +using GozareshgirProgramManager.Domain.CheckoutAgg.Repositories; +using GozareshgirProgramManager.Infrastructure.Persistence._Common; +using GozareshgirProgramManager.Infrastructure.Persistence.Context; +using Microsoft.EntityFrameworkCore; + +namespace GozareshgirProgramManager.Infrastructure.Persistence.Repositories; + +public class CheckoutRepository : RepositoryBase, ICheckoutRepository +{ + private readonly ProgramManagerDbContext _context; + public CheckoutRepository(ProgramManagerDbContext context) : base(context) + { + _context = context; + } + + public async Task> GetCheckoutListByIds(List checkoutIds) + { + return await _context.Checkouts.Where(x => checkoutIds.Contains(x.Id)).ToListAsync(); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/CustomerRepository.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/CustomerRepository.cs new file mode 100644 index 00000000..da0d9037 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/CustomerRepository.cs @@ -0,0 +1,38 @@ +using Microsoft.EntityFrameworkCore; +using GozareshgirProgramManager.Domain.CustomerAgg; +using GozareshgirProgramManager.Domain.CustomerAgg.Repositories; +using GozareshgirProgramManager.Infrastructure.Persistence.Context; + +namespace GozareshgirProgramManager.Infrastructure.Persistence.Repositories; + +public class CustomerRepository : ICustomerRepository +{ + private readonly ProgramManagerDbContext _context; + + public CustomerRepository(ProgramManagerDbContext context) + { + _context = context; + } + + public async Task GetByIdAsync(Guid id, CancellationToken cancellationToken = default) + { + return await _context.Customers + .FirstOrDefaultAsync(c => c.Id == id, cancellationToken); + } + + public async Task AddAsync(Customer customer, CancellationToken cancellationToken = default) + { + await _context.Customers.AddAsync(customer, cancellationToken); + } + + public void Update(Customer customer) + { + _context.Customers.Update(customer); + } + + public void Delete(Customer customer) + { + _context.Customers.Remove(customer); + } +} + diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/OrderRepository.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/OrderRepository.cs new file mode 100644 index 00000000..e69de29b diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/PhaseSectionRepository.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/PhaseSectionRepository.cs new file mode 100644 index 00000000..c582dffd --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/PhaseSectionRepository.cs @@ -0,0 +1,18 @@ +using GozareshgirProgramManager.Infrastructure.Persistence._Common; +using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Infrastructure.Persistence.Context; + +namespace GozareshgirProgramManager.Infrastructure.Persistence.Repositories; +public class PhaseSectionRepository : RepositoryBase, IPhaseSectionRepository +{ + private readonly ProgramManagerDbContext _programManagerDbContext; + public PhaseSectionRepository(ProgramManagerDbContext context) : base(context) + { + _programManagerDbContext = context; + } + +} + + + diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/ProductRepository.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/ProductRepository.cs new file mode 100644 index 00000000..e69de29b diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/ProjectPhaseRepository.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/ProjectPhaseRepository.cs new file mode 100644 index 00000000..81306c82 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/ProjectPhaseRepository.cs @@ -0,0 +1,60 @@ +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; +using Microsoft.EntityFrameworkCore; + +namespace GozareshgirProgramManager.Infrastructure.Persistence.Repositories; + +public class ProjectPhaseRepository : RepositoryBase, IProjectPhaseRepository +{ + private readonly ProgramManagerDbContext _context; + + public ProjectPhaseRepository(ProgramManagerDbContext context) : base(context) + { + _context = context; + } + + public Task GetWithTasksAsync(Guid phaseId) + { + return _context.ProjectPhases + .Include(p => p.Tasks) + .ThenInclude(t => t.Sections) + .ThenInclude(s => s.Skill) + .Include(p => p.Tasks) + .ThenInclude(t => t.Sections) + .ThenInclude(s => s.Activities) + .Include(p => p.Tasks) + .ThenInclude(t => t.Sections) + .ThenInclude(s => s.AdditionalTimes) + .FirstOrDefaultAsync(p => p.Id == phaseId); + } + + public Task> GetByProjectIdAsync(Guid projectId) + { + return _context.ProjectPhases + .Where(p => p.ProjectId == projectId) + .OrderBy(p => p.OrderIndex) + .ToListAsync(); + } + + public Task> GetPhasesWithAssignmentOverridesAsync() + { + return _context.ProjectPhases + .Where(p => p.HasAssignmentOverride) + .ToListAsync(); + } + + public Task> GetByStatusAsync(PhaseStatus status) + { + return _context.ProjectPhases + .Where(p => p.Status == status) + .ToListAsync(); + } + + public void Remove(ProjectPhase phase) + { + _context.ProjectPhases.Remove(phase); + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/ProjectRepository.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/ProjectRepository.cs new file mode 100644 index 00000000..21afca93 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/ProjectRepository.cs @@ -0,0 +1,70 @@ + +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; +using Microsoft.EntityFrameworkCore; + +namespace GozareshgirProgramManager.Infrastructure.Persistence.Repositories; + +public class ProjectRepository : RepositoryBase, IProjectRepository +{ + private readonly ProgramManagerDbContext _context; + + public ProjectRepository(ProgramManagerDbContext context) : base(context) + { + _context = context; + } + + public Task GetWithFullHierarchyAsync(Guid projectId) + { + return _context.Projects + .Include(p => p.Phases) + .ThenInclude(ph => ph.Tasks) + .ThenInclude(t => t.Sections) + .ThenInclude(s => s.Skill) + .Include(p => p.Phases) + .ThenInclude(ph => ph.Tasks) + .ThenInclude(t => t.Sections) + .ThenInclude(s => s.Activities) + .Include(p => p.Phases) + .ThenInclude(ph => ph.Tasks) + .ThenInclude(t => t.Sections) + .ThenInclude(s => s.AdditionalTimes) + .FirstOrDefaultAsync(p => p.Id == projectId); + } + + public Task GetWithPhasesAsync(Guid projectId) + { + return _context.Projects + .Include(p => p.Phases) + .FirstOrDefaultAsync(p => p.Id == projectId); + } + + public Task> GetByStatusAsync(ProjectStatus status) + { + return _context.Projects + .Where(p => p.Status == status) + .ToListAsync(); + } + + public Task> GetProjectsWithAssignmentOverridesAsync() + { + return _context.Projects + .Where(p => p.HasAssignmentOverride) + .ToListAsync(); + } + + public Task> SearchByNameAsync(string searchTerm) + { + return _context.Projects + .Where(p => p.Name.Contains(searchTerm)) + .ToListAsync(); + } + + public void Remove(Project project) + { + _context.Projects.Remove(project); + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/ProjectSectionRepository.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/ProjectSectionRepository.cs new file mode 100644 index 00000000..d2b115db --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/ProjectSectionRepository.cs @@ -0,0 +1,17 @@ +using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; +using GozareshgirProgramManager.Infrastructure.Persistence._Common; +using GozareshgirProgramManager.Infrastructure.Persistence.Context; +using Microsoft.EntityFrameworkCore; + +namespace GozareshgirProgramManager.Infrastructure.Persistence.Repositories; + +public class ProjectSectionRepository : RepositoryBase, IProjectSectionRepository +{ + private readonly ProgramManagerDbContext _programManagerDbContext; + public ProjectSectionRepository(ProgramManagerDbContext context) : base(context) + { + _programManagerDbContext = context; + } +} + diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/ProjectTaskRepository.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/ProjectTaskRepository.cs new file mode 100644 index 00000000..4e09e8cb --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/ProjectTaskRepository.cs @@ -0,0 +1,79 @@ +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; +using Microsoft.EntityFrameworkCore; +using TaskStatus = GozareshgirProgramManager.Domain.ProjectAgg.Enums.TaskStatus; + +namespace GozareshgirProgramManager.Infrastructure.Persistence.Repositories; + +public class ProjectTaskRepository : RepositoryBase, IProjectTaskRepository +{ + private readonly ProgramManagerDbContext _context; + + public ProjectTaskRepository(ProgramManagerDbContext context) : base(context) + { + _context = context; + } + + public Task GetWithSectionsAsync(Guid taskId) + { + return _context.ProjectTasks + .Include(t => t.Sections) + .ThenInclude(s => s.Skill) + .Include(t => t.Sections) + .ThenInclude(s => s.Activities) + .Include(t => t.Sections) + .ThenInclude(s => s.AdditionalTimes) + .FirstOrDefaultAsync(t => t.Id == taskId); + } + + public Task> GetByPhaseIdAsync(Guid phaseId) + { + return _context.ProjectTasks + .Where(t => t.PhaseId == phaseId) + .OrderBy(t => t.OrderIndex) + .ToListAsync(); + } + + public Task> GetTasksWithTimeOverridesAsync() + { + return _context.ProjectTasks + .Where(t => t.HasTimeOverride) + .ToListAsync(); + } + + public Task> GetTasksWithAssignmentOverridesAsync() + { + return _context.ProjectTasks + .Where(t => t.HasAssignmentOverride) + .ToListAsync(); + } + + public Task> GetByStatusAsync(TaskStatus status) + { + return _context.ProjectTasks + .Where(t => t.Status == status) + .ToListAsync(); + } + + public Task> GetByPriorityAsync(TaskPriority priority) + { + return _context.ProjectTasks + .Where(t => t.Priority == priority) + .ToListAsync(); + } + + public Task> GetAssignedToUserAsync(long userId) + { + return _context.ProjectTasks + .Where(t => t.Sections.Any(s => s.CurrentAssignedUserId == userId)) + .ToListAsync(); + } + + public void Remove(ProjectTask task) + { + _context.ProjectTasks.Remove(task); + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/RoleRepository.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/RoleRepository.cs new file mode 100644 index 00000000..01198c37 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/RoleRepository.cs @@ -0,0 +1,24 @@ +using GozareshgirProgramManager.Domain.RoleAgg.Entities; +using GozareshgirProgramManager.Domain.RoleAgg.Repositories; +using GozareshgirProgramManager.Infrastructure.Persistence._Common; +using GozareshgirProgramManager.Infrastructure.Persistence.Context; +using Microsoft.EntityFrameworkCore; + +namespace GozareshgirProgramManager.Infrastructure.Persistence.Repositories; + +public class RoleRepository : RepositoryBase, IRoleRepository +{ + private readonly ProgramManagerDbContext _context; + public RoleRepository(ProgramManagerDbContext context) : base(context) + { + _context = context; + } + + public async Task GetByGozareshgirRoleIdAsync(long? gozareshgirRolId) + { + return await _context.Roles.FirstOrDefaultAsync(x => x.GozareshgirRoleId == gozareshgirRolId); + } + + + +} \ No newline at end of file diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/SalaryPaymentSettingRepository.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/SalaryPaymentSettingRepository.cs new file mode 100644 index 00000000..a3d43ccd --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/SalaryPaymentSettingRepository.cs @@ -0,0 +1,60 @@ +using GozareshgirProgramManager.Application.Modules.SalaryPaymentSettings.Queries.GetSalarySettingToEdit; +using GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.DTOs; +using GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities; +using GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Repositories; +using GozareshgirProgramManager.Infrastructure.Persistence._Common; +using GozareshgirProgramManager.Infrastructure.Persistence.Context; +using Microsoft.EntityFrameworkCore; + +namespace GozareshgirProgramManager.Infrastructure.Persistence.Repositories; + +public class SalaryPaymentSettingRepository : RepositoryBase, ISalaryPaymentSettingRepository +{ + private readonly ProgramManagerDbContext _context; + public SalaryPaymentSettingRepository(ProgramManagerDbContext context) : base(context) + { + _context = context; + } + + + public async Task GetSalarySettingByUserId(long userId) + { + return await _context.SalaryPaymentSettings.FirstOrDefaultAsync(x => x.UserId == userId); + } + + + public async Task> GetAllSettings(List userIdList) + { + _context.SalaryPaymentSettings.AsNoTracking(); + var query = await _context.SalaryPaymentSettings.Where(s=> userIdList.Contains(s.UserId)) + .Join(_context.Users.AsNoTracking(), + setting => setting.UserId, + user => user.Id, + (setting, user) => new { setting, user } + ) + .Select(x => new UserSalarySettingDto + { + UserId = x.user.Id, + HolidayWorking = x.setting!.HolidayWorking, + FullName = x.user.FullName, + MonthlySalary = x.setting.MonthlySalary, + WorkingHoursListDto = x.setting.WorkingHoursList + .Where(wh => wh.IsActiveDay) + .Select(wh => new WorkingHoursListDto() + { + ShiftDuration = wh.ShiftDuration, + PersianDayOfWeek = wh.PersianDayOfWeek + }).ToList() + }) + .ToListAsync(); + + return query; + + } + + public void RemoveRangeSalarySettings(List removedItems) + { + _context.SalaryPaymentSettings.RemoveRange(removedItems); + + } +} \ No newline at end of file diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/SkillRepository.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/SkillRepository.cs new file mode 100644 index 00000000..935bfda3 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/SkillRepository.cs @@ -0,0 +1,16 @@ +using GozareshgirProgramManager.Domain.SkillAgg.Entities; +using GozareshgirProgramManager.Domain.SkillAgg.Repositories; +using GozareshgirProgramManager.Infrastructure.Persistence._Common; +using GozareshgirProgramManager.Infrastructure.Persistence.Context; +using Microsoft.EntityFrameworkCore; + +namespace GozareshgirProgramManager.Infrastructure.Persistence.Repositories; + +public class SkillRepository:RepositoryBase, ISkillRepository +{ + private readonly ProgramManagerDbContext _context; + public SkillRepository(ProgramManagerDbContext context) : base(context) + { + _context = context; + } +} \ No newline at end of file diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/TaskSectionActivityRepository.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/TaskSectionActivityRepository.cs new file mode 100644 index 00000000..4ae98bf7 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/TaskSectionActivityRepository.cs @@ -0,0 +1,83 @@ +using GozareshgirProgramManager.Application.Modules.Projects.DTOs; +using GozareshgirProgramManager.Application.Modules.Projects.Extensions; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; +using GozareshgirProgramManager.Infrastructure.Persistence._Common; +using GozareshgirProgramManager.Infrastructure.Persistence.Context; +using Microsoft.EntityFrameworkCore; + +namespace GozareshgirProgramManager.Infrastructure.Persistence.Repositories; + +public class TaskSectionActivityRepository : RepositoryBase, ITaskSectionActivityRepository +{ + private readonly ProgramManagerDbContext _programManagerDbContext; + + public TaskSectionActivityRepository(ProgramManagerDbContext programManagerDbContext) : base(programManagerDbContext) + { + _programManagerDbContext = programManagerDbContext; + } + + public async Task> GetBySectionIdAsync(Guid sectionId) + { + return await _programManagerDbContext.TaskSectionActivities + .Where(a => a.SectionId == sectionId).ToListAsync(); + } + + public async Task> GetByUserIdAsync(long userId) + { + return await _programManagerDbContext.TaskSectionActivities + .Where(x => x.UserId == userId).ToListAsync(); + } + + public async Task> GetActiveByUserAsync(long userId) + { + return await _programManagerDbContext.TaskSectionActivities + .Where(x => x.UserId == userId && x.IsActive) + .ToListAsync(); + } + + public async Task> GetByDateRangeAsync(DateTime from, DateTime to) + { + return await _programManagerDbContext.TaskSectionActivities + .Where(x => x.EndDate >= from && x.StartDate <= to).ToListAsync(); + } + + public async Task> GetByDateRangeUserIdAsync(DateTime from, DateTime to, long userId) + { + return await _programManagerDbContext.TaskSectionActivities + .Where(x => x.EndDate >= from && x.StartDate <= to && x.UserId == userId).ToListAsync(); + } + + public async Task GetTotalTimeSpentByUserInRangeAsync(long userId, DateTime from, DateTime to) + { + var data = await GetByDateRangeUserIdAsync(from, to, userId); + + return data.Aggregate(TimeSpan.Zero, (total, activity) => + { + var adjustedStart = activity.StartDate < from ? from : activity.StartDate; + var adjustedEnd = activity.EndDate > to ? to : (activity.EndDate ?? to); + return total.Add(adjustedEnd - adjustedStart); + }); + } + + public async Task> GetTotalTimeSpentPerUserInRangeAsync(DateTime from, + DateTime to) + { + var data = await GetByDateRangeAsync(from, to); + var result = data + .GroupBy(x => x.UserId) + .Select(group => + { + var totalTime = group.Aggregate(TimeSpan.Zero, (total, activity) => + { + var adjustedStart = activity.StartDate < from ? from : activity.StartDate; + var adjustedEnd = activity.EndDate > to ? to : (activity.EndDate ?? to); + return total.Add(adjustedEnd - adjustedStart); + }); + return (totalTime, group.Key); + }) + .ToList(); + + return result; + } +} \ No newline at end of file diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/TaskSectionRepository.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/TaskSectionRepository.cs new file mode 100644 index 00000000..80564915 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/TaskSectionRepository.cs @@ -0,0 +1,31 @@ +using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; +using GozareshgirProgramManager.Infrastructure.Persistence._Common; +using GozareshgirProgramManager.Infrastructure.Persistence.Context; +using Microsoft.EntityFrameworkCore; + +namespace GozareshgirProgramManager.Infrastructure.Persistence.Repositories; + +public class TaskSectionRepository:RepositoryBase,ITaskSectionRepository +{ + private readonly ProgramManagerDbContext _context; + public TaskSectionRepository(ProgramManagerDbContext context) : base(context) + { + _context = context; + } + + public async Task GetByIdWithActivitiesAsync(Guid id, CancellationToken cancellationToken = default) + { + return await _context.TaskSections + .Include(x => x.Activities) + .FirstOrDefaultAsync(x => x.Id == id, cancellationToken); + } + + public async Task GetByIdWithFullDataAsync(Guid id, CancellationToken cancellationToken = default) + { + return await _context.TaskSections + .Include(x => x.Activities) + .Include(x => x.AdditionalTimes) + .FirstOrDefaultAsync(x => x.Id == id, cancellationToken); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/UserRefreshTokenRepository.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/UserRefreshTokenRepository.cs new file mode 100644 index 00000000..7200e888 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/UserRefreshTokenRepository.cs @@ -0,0 +1,20 @@ +using System.Linq.Expressions; +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Domain.UserAgg.Entities; +using GozareshgirProgramManager.Domain.UserAgg.Repositories; +using GozareshgirProgramManager.Infrastructure.Persistence._Common; +using GozareshgirProgramManager.Infrastructure.Persistence.Context; +using Microsoft.EntityFrameworkCore; + +namespace GozareshgirProgramManager.Infrastructure.Persistence.Repositories; + +public class UserRefreshTokenRepository : RepositoryBase, IUserRefreshTokenRepository +{ + private readonly ProgramManagerDbContext _context; + public UserRefreshTokenRepository(ProgramManagerDbContext context) : base(context) + { + _context = context; + } + + +} \ No newline at end of file diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/UserRepository.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/UserRepository.cs new file mode 100644 index 00000000..7b83ef6e --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Repositories/UserRepository.cs @@ -0,0 +1,87 @@ +using GozareshgirProgramManager.Domain.UserAgg.Entities; +using GozareshgirProgramManager.Domain.UserAgg.Repositories; +using GozareshgirProgramManager.Infrastructure.Persistence._Common; +using GozareshgirProgramManager.Infrastructure.Persistence.Context; +using Microsoft.EntityFrameworkCore; + +namespace GozareshgirProgramManager.Infrastructure.Persistence.Repositories; + +public class UserRepository : RepositoryBase, IUserRepository +{ + private readonly ProgramManagerDbContext _context; + public UserRepository(ProgramManagerDbContext context) : base(context) + { + _context = context; + } + + public Task GetByIdAsync(long id) + { + throw new NotImplementedException(); + } + + public async Task GetByGozareshgirAccountId(long accountId) + { + return await _context.Users.FirstOrDefaultAsync(x => x.AccountId == accountId); + } + + public Task GetByEmailAsync(string email) + { + throw new NotImplementedException(); + } + + public Task GetByMobileAsync(string mobile) + { + throw new NotImplementedException(); + } + + public Task> GetAllAsync() + { + throw new NotImplementedException(); + } + + public Task> GetActiveUsersAsync() + { + throw new NotImplementedException(); + } + + public Task AddAsync(User user) + { + throw new NotImplementedException(); + } + + public void Update(User user) + { + throw new NotImplementedException(); + } + + public void Delete(User user) + { + throw new NotImplementedException(); + } + + public Task ExistsAsync(long id) + { + throw new NotImplementedException(); + } + + public Task UsernameExistsAsync(string username) + { + throw new NotImplementedException(); + } + + public Task EmailExistsAsync(string email) + { + throw new NotImplementedException(); + } + + public Task MobileExistsAsync(string mobile) + { + throw new NotImplementedException(); + } + + public async Task GetUserWithRolesByIdAsync(long userId, CancellationToken cancellationToken) + { + return await _context.Users.Include(x => x.RoleUser) + .FirstOrDefaultAsync(x=>x.Id == userId, cancellationToken); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Seed/DataSeeder.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Seed/DataSeeder.cs new file mode 100644 index 00000000..5afe7e82 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Seed/DataSeeder.cs @@ -0,0 +1,36 @@ +using System.Threading.Tasks; +using GozareshgirProgramManager.Infrastructure.Persistence.Context; +using GozareshgirProgramManager.Domain.SkillAgg.Entities; +using System.Linq; + +namespace GozareshgirProgramManager.Infrastructure.Persistence.Seed +{ + public class DataSeeder : IDataSeeder + { + private readonly ProgramManagerDbContext _dbContext; + public DataSeeder(ProgramManagerDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task SeedAllAsync() + { + await SeedSkillsIfEmptyAsync(); + // در آینده متدهای Seed دیگر را اینجا فراخوانی کنید + } + + private async Task SeedSkillsIfEmptyAsync() + { + if (!_dbContext.Skills.Any()) + { + _dbContext.Skills.AddRange( + new Skill("UI/UX Design"), + new Skill("Frontend"), + new Skill("Backend") + ); + await _dbContext.SaveChangesAsync(); + } + } + } +} + diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Seed/IDataSeeder.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Seed/IDataSeeder.cs new file mode 100644 index 00000000..2db95adc --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Seed/IDataSeeder.cs @@ -0,0 +1,10 @@ +using System.Threading.Tasks; + +namespace GozareshgirProgramManager.Infrastructure.Persistence.Seed +{ + public interface IDataSeeder + { + Task SeedAllAsync(); + } +} + diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/UnitOfWork.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/UnitOfWork.cs new file mode 100644 index 00000000..2a071185 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/UnitOfWork.cs @@ -0,0 +1,53 @@ +using GozareshgirProgramManager.Domain._Common; +using GozareshgirProgramManager.Infrastructure.Persistence.Context; +using MediatR; +using Microsoft.Identity.Client; +using GozareshgirProgramManager.Application._Common.Models; + +namespace GozareshgirProgramManager.Infrastructure.Persistence; + +public class UnitOfWork : IUnitOfWork +{ + private readonly ProgramManagerDbContext _context; + private readonly IPublisher _publisher; + + public UnitOfWork(ProgramManagerDbContext context, IPublisher publisher) + { + _context = context; + _publisher = publisher; + } + + public async Task SaveChangesAsync(CancellationToken cancellationToken = default) + { + // Publish Domain Events before saving + await PublishDomainEvents(cancellationToken); + + return await _context.SaveChangesAsync(cancellationToken); + } + + private async Task PublishDomainEvents(CancellationToken cancellationToken) + { + var domainEntities = _context.ChangeTracker + .Entries>() + .Where(x => x.Entity.DomainEvents.Any()) + .ToList(); + + var domainEvents = domainEntities + .SelectMany(x => x.Entity.DomainEvents) + .ToList(); + + domainEntities.ForEach(entity => entity.Entity.ClearDomainEvents()); + + foreach (var domainEvent in domainEvents) + { + var notificationType = typeof(DomainEventNotification<>).MakeGenericType(domainEvent.GetType()); + var notification = Activator.CreateInstance(notificationType, domainEvent); + + if (notification != null) + { + await _publisher.Publish(notification, cancellationToken); + } + } + } +} + diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/_Common/PropertyBuilderExtensions.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/_Common/PropertyBuilderExtensions.cs new file mode 100644 index 00000000..672d399e --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/_Common/PropertyBuilderExtensions.cs @@ -0,0 +1,21 @@ +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace GozareshgirProgramManager.Infrastructure.Persistence._Common; + +public static class PropertyBuilderExtensions +{ + public static PropertyBuilder HasTimeSpanConversion(this PropertyBuilder builder) + { + return builder.HasConversion( + v => v == TimeSpan.Zero ? "" : v.ToString(), + v => string.IsNullOrWhiteSpace(v) ? TimeSpan.Zero : TimeSpan.Parse(v) + ).HasMaxLength(30); + } + public static PropertyBuilder HasTimeSpanConversion(this PropertyBuilder builder) + { + return builder.HasConversion( + v =>v==null || v == TimeSpan.Zero ? "" : v.ToString(), + v => string.IsNullOrWhiteSpace(v) ? TimeSpan.Zero : TimeSpan.Parse(v) + ).HasMaxLength(30); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/_Common/RepositoryBase.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/_Common/RepositoryBase.cs new file mode 100644 index 00000000..def0cf17 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/_Common/RepositoryBase.cs @@ -0,0 +1,70 @@ +using System.Linq.Expressions; +using GozareshgirProgramManager.Domain._Common; +using Microsoft.EntityFrameworkCore; + +namespace GozareshgirProgramManager.Infrastructure.Persistence._Common; + +public class RepositoryBase : IRepository where T : class +{ + private readonly DbContext _context; + + public RepositoryBase(DbContext context) + { + _context = context; + } + + public void AddRange(IEnumerable entities) + { + _context.AddRange(entities); + } + public void Create(T entity) + { + _context.Add(entity); + } + + public async Task CreateAsync(T entity) + { + await _context.AddAsync(entity); + } + + + public bool ExistsIgnoreQueryFilter(Expression> expression) + { + return _context.Set().IgnoreQueryFilters().Any(expression); + } + + public bool Exists(Expression> expression) + { + return _context.Set().Any(expression); + } + + public T Get(TKey id) + { + return _context.Find(id); + } + + public async Task GetByIdAsync(TKey id) + { + return await _context.Set().FindAsync(id); + } + + public List Get() + { + return _context.Set().ToList(); + } + + public IQueryable GetQueryable() + { + return _context.Set().AsQueryable(); + } + + public void Remove(T entity) + { + _context.Set().Remove(entity); + } + + public void RemoveRange(IEnumerable entities) + { + _context.Set().RemoveRange(entities); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Services/Authentication/AuthHelper.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Services/Authentication/AuthHelper.cs new file mode 100644 index 00000000..ec2ccd4f --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Services/Authentication/AuthHelper.cs @@ -0,0 +1,217 @@ +using System.Security.Claims; +using GozareshgirProgramManager.Application._Common.Interfaces; +using Microsoft.AspNetCore.Http; + +namespace GozareshgirProgramManager.Infrastructure.Services.Authentication; + +/// +/// سرویس کمکی برای کار با JWT و HttpContext +/// این کلاس فقط با توکن و Context کار می‌کند و هیچ عملیات دیتابیسی ندارد +/// +public class AuthHelper : IAuthHelper +{ + private readonly IHttpContextAccessor _httpContextAccessor; + private readonly JwtTokenGenerator _jwtTokenGenerator; + + public AuthHelper( + IHttpContextAccessor httpContextAccessor, + JwtTokenGenerator jwtTokenGenerator) + { + _httpContextAccessor = httpContextAccessor; + _jwtTokenGenerator = jwtTokenGenerator; + } + + + /// + /// اعتبارسنجی توکن منقضی شده (بدون چک زمان) + /// + public ClaimsPrincipal? ValidateExpiredToken(string token) + { + return _jwtTokenGenerator.ValidateExpiredToken(token); + } + + /// + /// استخراج UserId از توکن (حتی اگر منقضی شده باشد) + /// + public long? GetUserIdFromToken(string token) + { + try + { + var principal = _jwtTokenGenerator.ValidateExpiredToken(token); + if (principal == null) return null; + + var userIdClaim = principal.FindFirst(ClaimTypes.NameIdentifier)?.Value; + return long.TryParse(userIdClaim, out var userId) ? userId : null; + } + catch + { + return null; + } + } + + /// + /// دریافت اطلاعات IP کاربر جاری + /// + public string? GetClientIpAddress() + { + return _httpContextAccessor.HttpContext?.Connection.RemoteIpAddress?.ToString(); + } + + /// + /// دریافت User Agent کاربر جاری + /// + public string? GetUserAgent() + { + return _httpContextAccessor.HttpContext?.Request.Headers["User-Agent"].ToString(); + } + + /// + /// دریافت Refresh Token از Header + /// + public string? GetRefreshTokenFromCookie() + { + return _httpContextAccessor.HttpContext?.Request.Cookies["rf-token"]; + } + + /// + /// بررسی احراز هویت کاربر جاری + /// + public bool IsAuthenticated() + { + return _httpContextAccessor.HttpContext?.User?.Identity?.IsAuthenticated ?? false; + } + + /// + /// دریافت شناسه کاربر جاری از Claims + /// + public long? GetCurrentUserId() + { + var userIdClaim = _httpContextAccessor.HttpContext?.User?.FindFirst("pm.userId")?.Value; + return long.TryParse(userIdClaim, out var userId) ? userId : null; + } + + /// + /// دریافت نام کاربری جاری از Claims + /// + public string? GetCurrentUserName() + { + return _httpContextAccessor.HttpContext?.User?.FindFirst(ClaimTypes.Name)?.Value; + } + + /// + /// دریافت نام کامل کاربر جاری از Claims + /// + public string? GetCurrentFullName() + { + return _httpContextAccessor.HttpContext?.User?.FindFirst("FullName")?.Value; + } + + // /// + // /// دریافت AccountId کاربر جاری از Claims + // /// + // public long? GetCurrentAccountId() + // { + // var accountIdClaim = _httpContextAccessor.HttpContext?.User?.FindFirst("AccountId")?.Value; + // return long.TryParse(accountIdClaim, out var accountId) ? accountId : null; + // } + + // /// + // /// دریافت نقش‌های کاربر جاری از Claims + // /// + // public List GetCurrentUserRoles() + // { + // var roles = _httpContextAccessor.HttpContext?.User?.FindAll(ClaimTypes.Role) + // .Select(c => c.Value) + // .ToList(); + // + // return roles ?? new List(); + // } + + // /// + // /// بررسی دسترسی کاربر به نقش خاص + // /// + // public bool HasRole(string roleName) + // { + // return _httpContextAccessor.HttpContext?.User?.IsInRole(roleName) ?? false; + // } + // + // /// + // /// بررسی دسترسی کاربر به یکی از نقش‌ها + // /// + // public bool HasAnyRole(params string[] roleNames) + // { + // return roleNames.Any(HasRole); + // } + // + // public void SignOut() + // { + // _httpContextAccessor.HttpContext?.Response.Cookies.Delete("rf-token"); + // _httpContextAccessor.HttpContext?.Response.Headers.Remove("Authorization"); + // } + // public LoginSession SignIn(long userId, string userName, string fullName, long accountId, List roles) + // { + // + // // 1. تولید Access Token + // var accessToken = GenerateAccessToken(userId, userName, fullName, accountId, roles); + // var accessTokenExpiration = DateTime.Now.AddMinutes(30); + // + // // 2. تولید Refresh Token + // var refreshToken = GenerateRefreshToken(); + // var refreshTokenExpiration = GetRefreshTokenExpiration(); + // + // // 3. ذخیره Refresh Token در Cookie + // _httpContextAccessor.HttpContext?.Response.Cookies.Append("rf-token", refreshToken, new CookieOptions + // { + // HttpOnly = true, + // Secure = true, + // SameSite = SameSiteMode.Lax, + // Expires = refreshTokenExpiration + // }); + // + // // 4. تنظیم Authorization Header (اختیاری - معمولاً کلاینت خودش این کار را می‌کند) + // _httpContextAccessor.HttpContext?.Response.Headers.Append("Authorization", $"Bearer {accessToken}"); + // + // return new LoginSession + // { + // AccessToken = accessToken, + // RefreshToken = refreshToken, + // RefreshTokenExpiration = refreshTokenExpiration, + // AccessTokenExpiration = accessTokenExpiration + // }; + // } + // + + // /// + // /// تولید Access Token + // /// + // public string GenerateAccessToken(long userId, string userName, string fullName, long? accountId, List roles) + // { + // return _jwtTokenGenerator.GenerateAccessToken(userId, userName, fullName, accountId, roles); + // } + + // /// + // /// تولید Refresh Token + // /// + // public string GenerateRefreshToken() + // { + // return _jwtTokenGenerator.GenerateRefreshToken(); + // } + // + // /// + // /// دریافت تاریخ انقضای Refresh Token + // /// + // public DateTime GetRefreshTokenExpiration() + // { + // return _jwtTokenGenerator.GetRefreshTokenExpiration(); + // } + + // /// + // /// اعتبارسنجی توکن و استخراج Claims + // /// + // public ClaimsPrincipal? ValidateToken(string token) + // { + // return _jwtTokenGenerator.ValidateToken(token); + // } + +} + diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Services/Authentication/JwtSettings.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Services/Authentication/JwtSettings.cs new file mode 100644 index 00000000..97d0b849 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Services/Authentication/JwtSettings.cs @@ -0,0 +1,14 @@ +namespace GozareshgirProgramManager.Infrastructure.Services.Authentication; +/// +/// تنظیمات JWT +/// +public class JwtSettings +{ + public int RefreshTokenExpirationDays { get; set; } = 7; + public int AccessTokenExpirationMinutes { get; set; } = 30; + public string Audience { get; set; } = string.Empty; + public string Issuer { get; set; } = string.Empty; + public string SecretKey { get; set; } = string.Empty; +} + + diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Services/Authentication/JwtTokenGenerator.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Services/Authentication/JwtTokenGenerator.cs new file mode 100644 index 00000000..2b15bd15 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Services/Authentication/JwtTokenGenerator.cs @@ -0,0 +1,153 @@ +using System.IdentityModel.Tokens.Jwt; +using System.Security.Claims; +using System.Security.Cryptography; +using System.Text; +using Microsoft.Extensions.Options; +using Microsoft.IdentityModel.Tokens; + +namespace GozareshgirProgramManager.Infrastructure.Services.Authentication; + +/// +/// سرویس تولید توکن JWT +/// +public class JwtTokenGenerator +{ + private readonly JwtSettings _jwtSettings; + + public JwtTokenGenerator(IOptions jwtSettings) + { + _jwtSettings = jwtSettings.Value; + } + + /// + /// تولید Access Token + /// + public string GenerateAccessToken(long userId, string userName, string fullName, long? accountId, List roles) + { + var claims = new List + { + new(ClaimTypes.NameIdentifier, userId.ToString()), + new(ClaimTypes.Name, userName), + new("FullName", fullName), + new(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()) + }; + + if (accountId.HasValue) + { + claims.Add(new Claim("AccountId", accountId.Value.ToString())); + } + + // افزودن نقش‌ها به Claims + claims.AddRange(roles.Select(role => new Claim(ClaimTypes.Role, role))); + + var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtSettings.SecretKey)); + var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); + var expires = DateTime.Now.AddMinutes(_jwtSettings.AccessTokenExpirationMinutes); + + var token = new JwtSecurityToken( + issuer: _jwtSettings.Issuer, + audience: _jwtSettings.Audience, + claims: claims, + expires: expires, + signingCredentials: credentials + ); + + return new JwtSecurityTokenHandler().WriteToken(token); + } + + /// + /// تولید Refresh Token + /// + public string GenerateRefreshToken() + { + var randomNumber = new byte[64]; + using var rng = RandomNumberGenerator.Create(); + rng.GetBytes(randomNumber); + return Convert.ToBase64String(randomNumber); + } + + /// + /// اعتبارسنجی و استخراج اطلاعات از توکن + /// + public ClaimsPrincipal? ValidateToken(string token) + { + try + { + var tokenHandler = new JwtSecurityTokenHandler(); + var key = Encoding.UTF8.GetBytes(_jwtSettings.SecretKey); + + var validationParameters = new TokenValidationParameters + { + ValidateIssuerSigningKey = true, + IssuerSigningKey = new SymmetricSecurityKey(key), + ValidateIssuer = true, + ValidIssuer = _jwtSettings.Issuer, + ValidateAudience = true, + ValidAudience = _jwtSettings.Audience, + ValidateLifetime = true, + ClockSkew = TimeSpan.Zero + }; + + var principal = tokenHandler.ValidateToken(token, validationParameters, out var validatedToken); + + if (validatedToken is not JwtSecurityToken jwtToken || + !jwtToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256, StringComparison.InvariantCultureIgnoreCase)) + { + return null; + } + + return principal; + } + catch + { + return null; + } + } + + /// + /// اعتبارسنجی توکن بدون چک کردن زمان انقضا (برای استخراج اطلاعات از توکن منقضی شده) + /// + public ClaimsPrincipal? ValidateExpiredToken(string token) + { + try + { + var tokenHandler = new JwtSecurityTokenHandler(); + var key = Encoding.UTF8.GetBytes(_jwtSettings.SecretKey); + + var validationParameters = new TokenValidationParameters + { + ValidateIssuerSigningKey = true, + IssuerSigningKey = new SymmetricSecurityKey(key), + ValidateIssuer = true, + ValidIssuer = _jwtSettings.Issuer, + ValidateAudience = true, + ValidAudience = _jwtSettings.Audience, + ValidateLifetime = false, // توکن منقضی شده هم قبول می‌شود + ClockSkew = TimeSpan.Zero + }; + + var principal = tokenHandler.ValidateToken(token, validationParameters, out var validatedToken); + + if (validatedToken is not JwtSecurityToken jwtToken || + !jwtToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256, StringComparison.InvariantCultureIgnoreCase)) + { + return null; + } + + return principal; + } + catch + { + return null; + } + } + + /// + /// دریافت تاریخ انقضای Refresh Token + /// + public DateTime GetRefreshTokenExpiration() + { + return DateTime.Now.AddDays(_jwtSettings.RefreshTokenExpirationDays); + } +} + diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Services/CacheService.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Services/CacheService.cs new file mode 100644 index 00000000..e69de29b diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Services/DateTimeService.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Services/DateTimeService.cs new file mode 100644 index 00000000..e69de29b diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Services/EmailService.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Services/EmailService.cs new file mode 100644 index 00000000..e69de29b diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Services/FileService.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Services/FileService.cs new file mode 100644 index 00000000..e69de29b diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Services/Role/PmRoleCommandService.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Services/Role/PmRoleCommandService.cs new file mode 100644 index 00000000..9ac4a2a8 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Services/Role/PmRoleCommandService.cs @@ -0,0 +1,41 @@ +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Application.Modules.Roles.Commands.CreateRole; +using GozareshgirProgramManager.Application.Modules.Roles.Commands.EditRole; +using MediatR; +using Shared.Contracts.PmRole.Commands; + +namespace GozareshgirProgramManager.Infrastructure.Services.Role; + +public class PmRoleCommandService: IPmRoleCommandService +{ + private readonly IMediator _mediator; + + public PmRoleCommandService(IMediator mediator) + { + _mediator = mediator; + } + + + + public async Task<(bool, string)> Create(CreatePmRoleDto command) + { + var request = new CreateRoleCommand + { + RoleName = command.RoleName, Permissions = command.Permissions, GozareshgirRoleId = command.GozareshgirRoleId + }; + var res = await _mediator.Send(request); + return (res.IsSuccess, res.ErrorMessage); + } + + public async Task<(bool, string)> Edit(CreatePmRoleDto command) + { + var request = new EditRoleCommand + { + RoleName = command.RoleName, + Permissions = command.Permissions, + GozareshgirRoleId = command.GozareshgirRoleId + }; + var res = await _mediator.Send(request); + return (res.IsSuccess, res.ErrorMessage); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Services/Role/PmRoleQueryService.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Services/Role/PmRoleQueryService.cs new file mode 100644 index 00000000..1f863f27 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Services/Role/PmRoleQueryService.cs @@ -0,0 +1,34 @@ +using GozareshgirProgramManager.Infrastructure.Persistence.Context; +using Microsoft.EntityFrameworkCore; +using Shared.Contracts.PmRole.Queries; + +namespace GozareshgirProgramManager.Infrastructure.Services.Role; + +public class PmRoleQueryService : IPmRoleQueryService +{ + private readonly ProgramManagerDbContext _programManagerDbContext; + + public PmRoleQueryService(ProgramManagerDbContext programManagerDbContext) + { + _programManagerDbContext = programManagerDbContext; + } + + public async Task> GetPmRoleList(long? gozareshgirRoleId) + { + var query = _programManagerDbContext.Roles.AsQueryable(); + if (gozareshgirRoleId != null && gozareshgirRoleId > 0) + query = query.Where(x => x.GozareshgirRoleId == gozareshgirRoleId); + var res = await query + .Select(p => new GetPmRolesDto() + { + Id = p.Id, + RoleName = p.RoleName, + GozareshgirRoleId = p.GozareshgirRoleId, + Permissions = p.Permissions.Select(x => x.Code).ToList() + + }) + .ToListAsync(); + + return res; + } +} \ No newline at end of file diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Services/User/PmUserQueryService.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Services/User/PmUserQueryService.cs new file mode 100644 index 00000000..1d6f9f04 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Services/User/PmUserQueryService.cs @@ -0,0 +1,22 @@ +using GozareshgirProgramManager.Application.Modules.Users.Queries.GetSingleUser; +using MediatR; +using Shared.Contracts.PmUser; + +namespace GozareshgirProgramManager.Infrastructure.Services.User; + +public class PmUserQueryService : IPmUserQueryService +{ + public readonly IMediator _mediator; + + public PmUserQueryService(IMediator mediator) + { + _mediator = mediator; + } + + public async Task GetCurrentPmUserIdFromAccountId(long accountId) + { + var query = new GetSingleUserQuery(accountId.ToString()); + var result = await _mediator.Send(query); + return result.Data?.Id ?? null; + } +} \ No newline at end of file diff --git a/Query.Bootstrapper/Query.Bootstrapper.csproj b/Query.Bootstrapper/Query.Bootstrapper.csproj index 2a4ad0a3..b41d79fc 100644 --- a/Query.Bootstrapper/Query.Bootstrapper.csproj +++ b/Query.Bootstrapper/Query.Bootstrapper.csproj @@ -1,13 +1,15 @@  - net8.0 + net10.0 enable enable - + + + diff --git a/Query/Query.csproj b/Query/Query.csproj index 38ac1440..b3fc6fdf 100644 --- a/Query/Query.csproj +++ b/Query/Query.csproj @@ -1,11 +1,16 @@  - net8.0 + net10.0 enable enable + + + + + diff --git a/ServiceHost/Areas/Admin/Controllers/GeneralController.cs b/ServiceHost/Areas/Admin/Controllers/GeneralController.cs new file mode 100644 index 00000000..64b27217 --- /dev/null +++ b/ServiceHost/Areas/Admin/Controllers/GeneralController.cs @@ -0,0 +1,29 @@ +using System.Globalization; +using Microsoft.AspNetCore.Mvc; +using ServiceHost.BaseControllers; + +namespace ServiceHost.Areas.Admin.Controllers; + +public class GeneralController:AdminBaseController +{ + /// + /// نمایش اطلاعات عمومی مانند تاریخ ها و سال ها + /// + /// + [HttpGet("Dates")] + public IActionResult GetDates() + { + var pc = new PersianCalendar(); + var now = DateTime.Now; + var currentYear = pc.GetYear(now); + var years = Enumerable.Range(1370, currentYear - 1370 + 1).ToList(); + var months = Enumerable.Range(1, 12).ToList(); + var currentDate = new { Year = currentYear, Month = pc.GetMonth(now), Day = pc.GetDayOfMonth(now) }; + return new JsonResult(new + { + years, + months, + currentDate + }); + } +} \ No newline at end of file diff --git a/ServiceHost/Areas/Admin/Controllers/ProgramManager/CheckoutController.cs b/ServiceHost/Areas/Admin/Controllers/ProgramManager/CheckoutController.cs new file mode 100644 index 00000000..29edd65c --- /dev/null +++ b/ServiceHost/Areas/Admin/Controllers/ProgramManager/CheckoutController.cs @@ -0,0 +1,93 @@ +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Application.Modules.Checkouts.Commands.CreateCheckout; +using GozareshgirProgramManager.Application.Modules.Checkouts.Queries.GetCheckoutList; +using GozareshgirProgramManager.Application.Modules.Checkouts.Queries.GetUserToGropCreate; +using GozareshgirProgramManager.Domain.CheckoutAgg.Enums; +using MediatR; +using Microsoft.AspNetCore.Mvc; +using ServiceHost.BaseControllers; + +namespace ServiceHost.Areas.Admin.Controllers.ProgramManager; + +public class CheckoutController : ProgramManagerBaseController +{ + private readonly IMediator _mediator; + + public CheckoutController(IMediator mediator) + { + _mediator = mediator; + } + + [HttpGet("GetUsersToGroupCreating")] + public async Task>> GetUserListWhoHaveSettings([FromQuery] GetUserToGroupCreatingQuery command) + { + + var res = await _mediator.Send(command); + + return res; + } + + //[HttpGet("TypeOfCheckoutHandlerDictionary")] + //public IActionResult GetTypeOfCheckoutHandlerDictionary() + //{ + // var names = Enum.GetNames(typeof(TypeOfCheckoutHandler)); + // List result = new List(); + + // foreach (var name in names) + // { + // if (name == "CreateInGroup") + // { + // result.Add("CreateInGroup ایجاد گروهی sample('1404', '8', UserIdList : [1,2,3] "); + // result.Add("------------------------------------------------------------------------------------------------------------------------------------"); + // } + + // if (name == "CreateInGroup") + // { + // result.Add("GroupEditing ویرایش گروهی sample(checkoutIdList : ['3fa85f64-5717-4562-b3fc-2c963f66afa6', '3fa85f64-5717-4562-b3fc-2c963f66afa6'])"); + // result.Add("------------------------------------------------------------------------------------------------------------------------------------"); + // } + + // if (name == "CreateInGroup") + // result.Add("SingleEdit ویرایش تکی sample(checkoutId : '3fa85f64-5717-4562-b3fc-2c963f66afa6')" ); + // } + // return Ok(result); + //} + + [HttpPost("Create")] + public async Task Create([FromBody] List? UserIdlist, string Year, string Month) + { + var createCommand = new CreateOrEditCheckoutCommand( + TypeOfCheckoutHandler.CreateInGroup, + Year, + Month,UserIdlist, new List()); + + + var res = await _mediator.Send(createCommand); + + return res; + } + + [HttpPost("Edit")] + public async Task EditSingleOrGroup([FromBody] List CheckoutIdList) + { + var createCommand = new CreateOrEditCheckoutCommand( + TypeOfCheckoutHandler.GroupEditing, + null, + null, null, CheckoutIdList); + + + var res = await _mediator.Send(createCommand); + + return res; + } + + + [HttpGet("GetCheckoutList")] + public async Task>>> GetCheckoutList([FromQuery] GetCheckoutListQuery command) + { + + var res = await _mediator.Send(command); + + return res; + } +} \ No newline at end of file diff --git a/ServiceHost/Areas/Admin/Controllers/ProgramManager/ProjectController.cs b/ServiceHost/Areas/Admin/Controllers/ProgramManager/ProjectController.cs new file mode 100644 index 00000000..266e72d4 --- /dev/null +++ b/ServiceHost/Areas/Admin/Controllers/ProgramManager/ProjectController.cs @@ -0,0 +1,102 @@ +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Application.Modules.Projects.Commands.AssignProject; +using GozareshgirProgramManager.Application.Modules.Projects.Commands.ChangeStatusSection; +using GozareshgirProgramManager.Application.Modules.Projects.Commands.CreateProject; +using GozareshgirProgramManager.Application.Modules.Projects.Commands.DeleteProject; +using GozareshgirProgramManager.Application.Modules.Projects.Commands.EditProject; +using GozareshgirProgramManager.Application.Modules.Projects.Commands.SetTimeProject; +using GozareshgirProgramManager.Application.Modules.Projects.Commands.TransferSection; +using GozareshgirProgramManager.Application.Modules.Projects.Queries.GetProjectAssignDetails; +using GozareshgirProgramManager.Application.Modules.Projects.Queries.GetProjectsList; +using GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectBoardList; +using GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectSetTimeDetails; +using MediatR; +using Microsoft.AspNetCore.Mvc; +using ServiceHost.BaseControllers; + +namespace ServiceHost.Areas.Admin.Controllers.ProgramManager; + +public class ProjectController : ProgramManagerBaseController +{ + private readonly IMediator _mediator; + + public ProjectController(IMediator mediator) + { + _mediator = mediator; + } + + [HttpGet] + public async Task>> Get([FromQuery]GetProjectsListQuery query) + { + var res=await _mediator.Send(query); + return res; + } + + [HttpPost] + public async Task> Create([FromBody] CreateProjectCommand command) + { + var res=await _mediator.Send(command); + return res; + } + + [HttpPut] + public async Task> Edit([FromBody] EditProjectCommand command) + { + var res=await _mediator.Send(command); + return res; + } + + [HttpDelete] + public async Task> Delete([FromQuery] DeleteProjectCommand command) + { + var res=await _mediator.Send(command); + return res; + } + + [HttpGet("assign")] + public async Task>> GetAssignableProjects(GetProjectAssignDetailsQuery query) + { + var res=await _mediator.Send(query); + return res; + } + + [HttpPost("assign")] + public async Task> Assign(AssignProjectCommand command) + { + var res=await _mediator.Send(command); + return res; + } + [HttpGet("set-time")] + public async Task>> GetSetTimeProjectDetails(ProjectSetTimeDetailsQuery query) + { + var res=await _mediator.Send(query); + return res; + } + [HttpPost("set-time")] + public async Task> SetTimeProject(SetTimeProjectCommand command) + { + var res=await _mediator.Send(command); + return res; + } + + [HttpPost("change-status")] + public async Task> ChangeStatus(ChangeStatusSectionCommand command) + { + var res = await _mediator.Send(command); + return res; + } + + [HttpPost("transfer-section")] + public async Task> TransferSection([FromBody] TransferSectionCommand command) + { + var res = await _mediator.Send(command); + return res; + } + + [HttpGet("board")] + public async Task>>> GetProjectBoard([FromQuery] ProjectBoardListQuery query) + { + var res = await _mediator.Send(query); + return res; + } +} \ No newline at end of file diff --git a/ServiceHost/Areas/Admin/Controllers/ProgramManager/RoleController.cs b/ServiceHost/Areas/Admin/Controllers/ProgramManager/RoleController.cs new file mode 100644 index 00000000..d7994d7a --- /dev/null +++ b/ServiceHost/Areas/Admin/Controllers/ProgramManager/RoleController.cs @@ -0,0 +1,46 @@ +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Application.Modules.Roles.Commands.CreateRole; +using GozareshgirProgramManager.Application.Modules.Roles.Commands.EditRole; +using GozareshgirProgramManager.Application.Modules.Roles.Queries.GetRoles; +using MediatR; +using Microsoft.AspNetCore.Mvc; +using ServiceHost.BaseControllers; + +namespace ServiceHost.Areas.Admin.Controllers.ProgramManager; + +public class RoleController : ProgramManagerBaseController +{ + private readonly IMediator _mediator; + + public RoleController(IMediator mediator) + { + _mediator = mediator; + } + + + [HttpGet] + public async Task>> Get([FromQuery] GetRolesQuery query) + { + var res = await _mediator.Send(query); + return res; + } + + + [HttpPost] + public async Task> Create([FromBody] CreateRoleCommand command) + { + var res = await _mediator.Send(command); + return res; + } + + + + [HttpPost("edit")] + public async Task> Edit([FromBody] EditRoleCommand command) + { + var res = await _mediator.Send(command); + return res; + } + + +} \ No newline at end of file diff --git a/ServiceHost/Areas/Admin/Controllers/ProgramManager/SalaryPaymentSettingsController.cs b/ServiceHost/Areas/Admin/Controllers/ProgramManager/SalaryPaymentSettingsController.cs new file mode 100644 index 00000000..bc4784e2 --- /dev/null +++ b/ServiceHost/Areas/Admin/Controllers/ProgramManager/SalaryPaymentSettingsController.cs @@ -0,0 +1,67 @@ +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Application.Modules.SalaryPaymentSettings.Commands.CreateSalarySettings; +using GozareshgirProgramManager.Application.Modules.SalaryPaymentSettings.Commands.EditSalarySettings; +using GozareshgirProgramManager.Application.Modules.SalaryPaymentSettings.Queries.GetSalarySettingToEdit; +using GozareshgirProgramManager.Application.Modules.SalaryPaymentSettings.Queries.GetUserListWhoHaveSettings; +using GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Enums; +using MediatR; +using Microsoft.AspNetCore.Mvc; +using ServiceHost.BaseControllers; + +namespace ServiceHost.Areas.Admin.Controllers.ProgramManager; + +public class SalaryPaymentSettingsController : ProgramManagerBaseController +{ + private readonly IMediator _mediator; + + public SalaryPaymentSettingsController(IMediator mediator) + { + _mediator = mediator; + } + + [HttpGet("PersianDayOfWeekDictionary")] + public IActionResult GetPersianDayOfWeekDictionary() + { + var names = Enum.GetNames(typeof(PersianDayOfWeek)); + + return Ok(names); + } + + [HttpGet("GetUsers")] + public async Task>> GetUserListWhoHaveSettings([FromQuery] GetUserListWhoHaveSettingsQuery command) + { + + var res = await _mediator.Send(command); + + return res; + } + + [HttpGet("GetToEdit/{UserId}")] + public async Task>> GetSalarySettingsByUserId(long UserId) + { + var query = new GetSalarySettingToEditQuery(UserId); + var res = await _mediator.Send(query); + + return res; + } + + [HttpPost("edit")] + public async Task> Edit([FromBody] EditSalarySettingsCommand command) + { + var res = await _mediator.Send(command); + return res; + } + + + [HttpPost("create")] + public async Task> Create([FromBody] CreateSalarySettingsCommand command) + { + var res = await _mediator.Send(command); + return res; + + } + + + +} + diff --git a/ServiceHost/Areas/Admin/Controllers/ProgramManager/SkillController.cs b/ServiceHost/Areas/Admin/Controllers/ProgramManager/SkillController.cs new file mode 100644 index 00000000..0966a65a --- /dev/null +++ b/ServiceHost/Areas/Admin/Controllers/ProgramManager/SkillController.cs @@ -0,0 +1,24 @@ +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Application.Modules.Skills.Queries.GetSkillList; +using MediatR; +using Microsoft.AspNetCore.Mvc; +using ServiceHost.BaseControllers; + +namespace ServiceHost.Areas.Admin.Controllers.ProgramManager; + +public class SkillController:ProgramManagerBaseController +{ + private readonly IMediator _mediator; + + public SkillController(IMediator mediator) + { + _mediator = mediator; + } + + [HttpGet] + public async Task>> GetList([FromQuery]GetSkillListQuery query) + { + var res = await _mediator.Send(query); + return res; + } +} \ No newline at end of file diff --git a/ServiceHost/Areas/Admin/Controllers/ProgramManager/UserController.cs b/ServiceHost/Areas/Admin/Controllers/ProgramManager/UserController.cs new file mode 100644 index 00000000..03ef60b8 --- /dev/null +++ b/ServiceHost/Areas/Admin/Controllers/ProgramManager/UserController.cs @@ -0,0 +1,67 @@ +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Application.Modules.Users.Commands.CreateUser; +using GozareshgirProgramManager.Application.Modules.Users.Commands.EditUser; +using GozareshgirProgramManager.Application.Modules.Users.Queries.GetSingleUser; +using GozareshgirProgramManager.Application.Modules.Users.Queries.GetUsers; +using GozareshgirProgramManager.Application.Modules.Users.Queries.GetUserSelectList; +using MediatR; +using Microsoft.AspNetCore.Mvc; +using ServiceHost.BaseControllers; + +namespace ServiceHost.Areas.Admin.Controllers.ProgramManager; + +public class UserController : ProgramManagerBaseController +{ + private readonly IMediator _mediator; + + + public UserController(IMediator mediator) + { + _mediator = mediator; + } + + + [HttpGet] + public async Task>> Get([FromQuery] GetUsersQuery query) + { + var res = await _mediator.Send(query); + return res; + } + + + [HttpGet("{accountId}")] + public async Task>> GetUserByAccountId(string accountId) + { + var query = new GetSingleUserQuery(accountId); + var res = await _mediator.Send(query); + + return res; + } + + [HttpGet("GetUserSelectList")] + public async Task>> GetUserSelectList() + { + var query = new GetUserSelectListQuery(); + var res = await _mediator.Send(query); + + return res; + } + + + [HttpPost("create")] + public async Task> Create([FromBody] CreateUserCommand command) + { + var res = await _mediator.Send(command); + return res; + } + + + [HttpPost("edit")] + public async Task> Edit([FromBody] EditUserCommand command) + { + var res = await _mediator.Send(command); + return res; + } + + +} \ No newline at end of file diff --git a/ServiceHost/Areas/Admin/Pages/Company/Checkouts/CreateLoadList.cshtml b/ServiceHost/Areas/Admin/Pages/Company/Checkouts/CreateLoadList.cshtml index e49343e6..318d6972 100644 --- a/ServiceHost/Areas/Admin/Pages/Company/Checkouts/CreateLoadList.cshtml +++ b/ServiceHost/Areas/Admin/Pages/Company/Checkouts/CreateLoadList.cshtml @@ -1,5 +1,4 @@ -@using Microsoft.CodeAnalysis.CSharp.Syntax -@model CompanyManagment.App.Contracts.Checkout.CreateCheckoutListViewModel +@model CompanyManagment.App.Contracts.Checkout.CreateCheckoutListViewModel @{ var i = 1; var b = 0; diff --git a/ServiceHost/Areas/Admin/Pages/Company/Checkouts/Details.cshtml b/ServiceHost/Areas/Admin/Pages/Company/Checkouts/Details.cshtml index 95c72111..1a6af7f7 100644 --- a/ServiceHost/Areas/Admin/Pages/Company/Checkouts/Details.cshtml +++ b/ServiceHost/Areas/Admin/Pages/Company/Checkouts/Details.cshtml @@ -1,5 +1,4 @@ -@using System.Security.Cryptography.X509Certificates -@model CompanyManagment.App.Contracts.Checkout.CheckoutViewModel +@model CompanyManagment.App.Contracts.Checkout.CheckoutViewModel @{ var totalDays = Model.MonthlyRollCall?.Count ?? 0; var rightSideDays = totalDays / 2; diff --git a/ServiceHost/Areas/Admin/Pages/Company/Checkouts/Index.cshtml b/ServiceHost/Areas/Admin/Pages/Company/Checkouts/Index.cshtml index e416cff2..929dc0c9 100644 --- a/ServiceHost/Areas/Admin/Pages/Company/Checkouts/Index.cshtml +++ b/ServiceHost/Areas/Admin/Pages/Company/Checkouts/Index.cshtml @@ -1,5 +1,4 @@ @page -@using CompanyManagment.App.Contracts.PersonalContractingParty @model ServiceHost.Areas.Admin.Pages.Company.Checkouts.IndexModel @{ diff --git a/ServiceHost/Areas/Admin/Pages/Company/ContractingParties/Index.cshtml b/ServiceHost/Areas/Admin/Pages/Company/ContractingParties/Index.cshtml index f2e5c44c..51973794 100644 --- a/ServiceHost/Areas/Admin/Pages/Company/ContractingParties/Index.cshtml +++ b/ServiceHost/Areas/Admin/Pages/Company/ContractingParties/Index.cshtml @@ -1,5 +1,4 @@ @page -@using CompanyManagment.App.Contracts.PersonalContractingParty @model ServiceHost.Areas.Admin.Pages.Company.ContractingParties.IndexModel @{ diff --git a/ServiceHost/Areas/Admin/Pages/Company/Contracts/Index.cshtml b/ServiceHost/Areas/Admin/Pages/Company/Contracts/Index.cshtml index 4865d1a4..778f0284 100644 --- a/ServiceHost/Areas/Admin/Pages/Company/Contracts/Index.cshtml +++ b/ServiceHost/Areas/Admin/Pages/Company/Contracts/Index.cshtml @@ -1,5 +1,4 @@ @page -@using CompanyManagment.App.Contracts.PersonalContractingParty @model ServiceHost.Areas.Admin.Pages.Company.Contracts.IndexModel diff --git a/ServiceHost/Areas/Admin/Pages/Company/Employees/Create.cshtml b/ServiceHost/Areas/Admin/Pages/Company/Employees/Create.cshtml index c0921767..659894e6 100644 --- a/ServiceHost/Areas/Admin/Pages/Company/Employees/Create.cshtml +++ b/ServiceHost/Areas/Admin/Pages/Company/Employees/Create.cshtml @@ -1,5 +1,4 @@ -@using _0_Framework.Application -@model CompanyManagment.App.Contracts.Employee.CreateEmployee +@model CompanyManagment.App.Contracts.Employee.CreateEmployee @{ var adminVersion = _0_Framework.Application.Version.AdminVersion; diff --git a/ServiceHost/Areas/Admin/Pages/Company/Employees/CreateEmployee.cshtml b/ServiceHost/Areas/Admin/Pages/Company/Employees/CreateEmployee.cshtml index 28543bbb..e48dfc71 100644 --- a/ServiceHost/Areas/Admin/Pages/Company/Employees/CreateEmployee.cshtml +++ b/ServiceHost/Areas/Admin/Pages/Company/Employees/CreateEmployee.cshtml @@ -1,5 +1,4 @@ -@using _0_Framework.Application -@model CompanyManagment.App.Contracts.Employee.CreateEmployee +@model CompanyManagment.App.Contracts.Employee.CreateEmployee @{ var adminVersion = _0_Framework.Application.Version.AdminVersion; diff --git a/ServiceHost/Areas/Admin/Pages/Company/Employees/Index.cshtml b/ServiceHost/Areas/Admin/Pages/Company/Employees/Index.cshtml index dcfb2559..845c6b61 100644 --- a/ServiceHost/Areas/Admin/Pages/Company/Employees/Index.cshtml +++ b/ServiceHost/Areas/Admin/Pages/Company/Employees/Index.cshtml @@ -1,5 +1,4 @@ @page -@using CompanyManagment.App.Contracts.PersonalContractingParty @model ServiceHost.Areas.Admin.Pages.Company.Employees.IndexModel @{ diff --git a/ServiceHost/Areas/Admin/Pages/Company/Employers/Index.cshtml b/ServiceHost/Areas/Admin/Pages/Company/Employers/Index.cshtml index 64e33aaf..8ecf3052 100644 --- a/ServiceHost/Areas/Admin/Pages/Company/Employers/Index.cshtml +++ b/ServiceHost/Areas/Admin/Pages/Company/Employers/Index.cshtml @@ -1,5 +1,4 @@ @page -@using CompanyManagment.App.Contracts.PersonalContractingParty @model ServiceHost.Areas.Admin.Pages.Company.Employers.IndexModel @{ diff --git a/ServiceHost/Areas/Admin/Pages/Company/Holidays/Index.cshtml b/ServiceHost/Areas/Admin/Pages/Company/Holidays/Index.cshtml index 69c2dad9..75e213a8 100644 --- a/ServiceHost/Areas/Admin/Pages/Company/Holidays/Index.cshtml +++ b/ServiceHost/Areas/Admin/Pages/Company/Holidays/Index.cshtml @@ -1,7 +1,4 @@ @page -@using CompanyManagment.App.Contracts.PersonalContractingParty -@using Microsoft.EntityFrameworkCore -@using CompanyManagment.App.Contracts.Holiday @model ServiceHost.Areas.Admin.Pages.Company.Holidays.IndexModel @{ diff --git a/ServiceHost/Areas/Admin/Pages/Company/InsuranceList/_Partials/OperationsModal.cshtml b/ServiceHost/Areas/Admin/Pages/Company/InsuranceList/_Partials/OperationsModal.cshtml index c8d15d51..84bc4fd5 100644 --- a/ServiceHost/Areas/Admin/Pages/Company/InsuranceList/_Partials/OperationsModal.cshtml +++ b/ServiceHost/Areas/Admin/Pages/Company/InsuranceList/_Partials/OperationsModal.cshtml @@ -1,5 +1,4 @@ @using CompanyManagment.App.Contracts.InsuranceList.Enums -@using Microsoft.AspNetCore.Mvc.TagHelpers @model CompanyManagment.App.Contracts.InsuranceList.InsuranceListConfirmOperation @{ diff --git a/ServiceHost/Areas/Admin/Pages/Company/Jobs/Index.cshtml b/ServiceHost/Areas/Admin/Pages/Company/Jobs/Index.cshtml index 9e035d35..a4e80527 100644 --- a/ServiceHost/Areas/Admin/Pages/Company/Jobs/Index.cshtml +++ b/ServiceHost/Areas/Admin/Pages/Company/Jobs/Index.cshtml @@ -1,5 +1,4 @@ @page -@using CompanyManagment.App.Contracts.PersonalContractingParty @model ServiceHost.Areas.Admin.Pages.Company.Jobs.IndexModel @{ diff --git a/ServiceHost/Areas/Admin/Pages/Company/MandatoryHours/Index.cshtml b/ServiceHost/Areas/Admin/Pages/Company/MandatoryHours/Index.cshtml index c1370298..fc059cf3 100644 --- a/ServiceHost/Areas/Admin/Pages/Company/MandatoryHours/Index.cshtml +++ b/ServiceHost/Areas/Admin/Pages/Company/MandatoryHours/Index.cshtml @@ -1,5 +1,4 @@ @page -@using CompanyManagment.App.Contracts.PersonalContractingParty @model ServiceHost.Areas.Admin.Pages.Company.MandatoryHours.IndexModel @{ diff --git a/ServiceHost/Areas/Admin/Pages/Company/Representative/Index.cshtml b/ServiceHost/Areas/Admin/Pages/Company/Representative/Index.cshtml index 1065f4e7..c9143498 100644 --- a/ServiceHost/Areas/Admin/Pages/Company/Representative/Index.cshtml +++ b/ServiceHost/Areas/Admin/Pages/Company/Representative/Index.cshtml @@ -1,5 +1,4 @@ @page -@using CompanyManagment.App.Contracts.Representative @model ServiceHost.Areas.Admin.Pages.Company.Representative.IndexModel @{ diff --git a/ServiceHost/Areas/Admin/Pages/Company/SmsResult/SmsSettings.cshtml b/ServiceHost/Areas/Admin/Pages/Company/SmsResult/SmsSettings.cshtml index ee6275a3..279d822f 100644 --- a/ServiceHost/Areas/Admin/Pages/Company/SmsResult/SmsSettings.cshtml +++ b/ServiceHost/Areas/Admin/Pages/Company/SmsResult/SmsSettings.cshtml @@ -1,6 +1,4 @@ @page -@using _0_Framework.Application.Enums -@using Microsoft.AspNetCore.Mvc.TagHelpers @model ServiceHost.Areas.Admin.Pages.Company.SmsResult.SmsSettingsModel @Html.AntiForgeryToken() @{ diff --git a/ServiceHost/Areas/Admin/Pages/Company/Workshops/EditWorkshop.cshtml b/ServiceHost/Areas/Admin/Pages/Company/Workshops/EditWorkshop.cshtml index 21ea2cfe..4a24360f 100644 --- a/ServiceHost/Areas/Admin/Pages/Company/Workshops/EditWorkshop.cshtml +++ b/ServiceHost/Areas/Admin/Pages/Company/Workshops/EditWorkshop.cshtml @@ -1,6 +1,5 @@ @page @using _0_Framework.Application -@using Microsoft.AspNetCore.Mvc.TagHelpers @model ServiceHost.Areas.Admin.Pages.Company.Workshops.EditWorkshopModel @{ string adminVersion = _0_Framework.Application.Version.AdminVersion; diff --git a/ServiceHost/Areas/Admin/Pages/Company/Workshops/Index.cshtml b/ServiceHost/Areas/Admin/Pages/Company/Workshops/Index.cshtml index 61c89eca..4a82840a 100644 --- a/ServiceHost/Areas/Admin/Pages/Company/Workshops/Index.cshtml +++ b/ServiceHost/Areas/Admin/Pages/Company/Workshops/Index.cshtml @@ -1,5 +1,4 @@ @page -@using CompanyManagment.App.Contracts.PersonalContractingParty @model ServiceHost.Areas.Admin.Pages.Company.Workshops.IndexModel @{ diff --git a/ServiceHost/Areas/Admin/Pages/Company/Workshops/_EditForms/FormPermissionAccount.cshtml b/ServiceHost/Areas/Admin/Pages/Company/Workshops/_EditForms/FormPermissionAccount.cshtml index ac030de9..27765263 100644 --- a/ServiceHost/Areas/Admin/Pages/Company/Workshops/_EditForms/FormPermissionAccount.cshtml +++ b/ServiceHost/Areas/Admin/Pages/Company/Workshops/_EditForms/FormPermissionAccount.cshtml @@ -1,5 +1,4 @@ @using AccountManagement.Application.Contracts.Account -@using Microsoft.AspNetCore.Mvc.TagHelpers @model CompanyManagment.App.Contracts.Workshop.EditWorkshop @{ diff --git a/ServiceHost/Areas/Admin/Pages/Index.cshtml b/ServiceHost/Areas/Admin/Pages/Index.cshtml index a36a3d4b..3e1a948d 100644 --- a/ServiceHost/Areas/Admin/Pages/Index.cshtml +++ b/ServiceHost/Areas/Admin/Pages/Index.cshtml @@ -2,7 +2,6 @@ @page @using _0_Framework.Application @using AccountManagement.Application.Contracts.TicketAccessAccount -@using Microsoft.AspNetCore.Mvc.TagHelpers @model ServiceHost.Areas.Admin.Pages.IndexModel @inject ITicketAccessAccountApplication TicketAccessAccount; @inject IAuthHelper authHelper; diff --git a/ServiceHost/Areas/Admin/Pages/Shared/_AdminLayout.cshtml b/ServiceHost/Areas/Admin/Pages/Shared/_AdminLayout.cshtml index 2c17b1cf..a6e21401 100644 --- a/ServiceHost/Areas/Admin/Pages/Shared/_AdminLayout.cshtml +++ b/ServiceHost/Areas/Admin/Pages/Shared/_AdminLayout.cshtml @@ -1,6 +1,4 @@ -@using Microsoft.AspNetCore.Razor.Language.Intermediate -@using _0_Framework.Application -@using Version = _0_Framework.Application.Version +@using Version = _0_Framework.Application.Version @inject _0_Framework.Application.IAuthHelper AuthHelper; @{ diff --git a/ServiceHost/Areas/Admin/Pages/Shared/_Menu.cshtml b/ServiceHost/Areas/Admin/Pages/Shared/_Menu.cshtml index 33621097..2734ee67 100644 --- a/ServiceHost/Areas/Admin/Pages/Shared/_Menu.cshtml +++ b/ServiceHost/Areas/Admin/Pages/Shared/_Menu.cshtml @@ -1,6 +1,5 @@ @using _0_Framework.Application @using AccountManagement.Domain.TicketAccessAccountAgg -@using Microsoft.AspNetCore.Mvc.TagHelpers @using Microsoft.Extensions.Options @inject _0_Framework.Application.IAuthHelper AuthHelper; @inject ITicketAccessAccountRepository TicketAccessAccount; diff --git a/ServiceHost/Areas/Admin/Pages/_ViewImports.cshtml b/ServiceHost/Areas/Admin/Pages/_ViewImports.cshtml index 1dd320b1..100a2f8a 100644 --- a/ServiceHost/Areas/Admin/Pages/_ViewImports.cshtml +++ b/ServiceHost/Areas/Admin/Pages/_ViewImports.cshtml @@ -1,4 +1,3 @@ -@using ServiceHost -@namespace ServiceHost.Pages +@namespace ServiceHost.Areas.Admin.Pages @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers @addTagHelper *, ServiceHost \ No newline at end of file diff --git a/ServiceHost/BaseControllers/ProgramManagerBaseController.cs b/ServiceHost/BaseControllers/ProgramManagerBaseController.cs new file mode 100644 index 00000000..db83d401 --- /dev/null +++ b/ServiceHost/BaseControllers/ProgramManagerBaseController.cs @@ -0,0 +1,14 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace ServiceHost.BaseControllers; + +[Authorize(Policy = "AdminArea")] +[Area("ProgramManager")] +[ApiExplorerSettings(GroupName = "ProgramManager")] +[Route("api/[area]/[controller]")] +public class ProgramManagerBaseController : ControllerBase +{ + +} + diff --git a/ServiceHost/Program.cs b/ServiceHost/Program.cs index d6882906..40ca19b2 100644 --- a/ServiceHost/Program.cs +++ b/ServiceHost/Program.cs @@ -1,18 +1,11 @@ -using System; -using System.Collections.Generic; -using System.Reflection; +using System.Reflection; using _0_Framework.Application.Sms; using _0_Framework.Application; using AccountManagement.Configuration; using Microsoft.AspNetCore.Authentication.Cookies; -using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http.Features; using PersonalContractingParty.Config; using ServiceHost; -using Microsoft.AspNetCore.Http; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; using Query.Bootstrapper; using ServiceHost.Hubs; using ServiceHost.MiddleWare; @@ -20,23 +13,24 @@ using WorkFlow.Infrastructure.Config; using _0_Framework.Application.UID; using _0_Framework.Exceptions.Handler; using _0_Framework.Application.FaceEmbedding; -using Microsoft.OpenApi.Models; using ServiceHost.Test; using System.Text.Json.Serialization; -using System.Text.Json; using _0_Framework.InfraStructure.Mongo; -using Bogus; using CompanyManagment.App.Contracts.Hubs; using CompanyManagment.EFCore.Services; -using Microsoft.AspNetCore.CookiePolicy; using Microsoft.AspNetCore.Mvc.Infrastructure; using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Diagnostics; using MongoDB.Driver; using Parbad.Builder; using Parbad.Gateway.Sepehr; using Swashbuckle.AspNetCore.SwaggerUI; using AccountManagement.Domain.InternalApiCaller; +using FluentValidation; +using GozareshgirProgramManager.Application._Bootstrapper; +using GozareshgirProgramManager.Application.Modules.Users.Commands.CreateUser; +using GozareshgirProgramManager.Infrastructure; +using GozareshgirProgramManager.Infrastructure.Persistence.Seed; +using Microsoft.OpenApi; var builder = WebApplication.CreateBuilder(args); @@ -55,6 +49,11 @@ var connectionString = builder.Configuration.GetConnectionString("MesbahDb"); var connectionStringTestDb = builder.Configuration.GetConnectionString("TestDb"); var connectionStringProgramManager = builder.Configuration.GetConnectionString("ProgramManagerDb"); + +builder.Services.AddProgramManagerApplication(); +builder.Services.AddProgramManagerInfrastructure(builder.Configuration); +builder.Services.AddValidatorsFromAssemblyContaining(); +builder.Services.AddScoped(); #region MongoDb var mongoConnectionSection = builder.Configuration.GetSection("MongoDb"); @@ -216,6 +215,7 @@ builder.Services.AddSignalR(); builder.Services.AddSwaggerGen(options => { options.UseInlineDefinitionsForEnums(); + options.CustomSchemaIds(type => type.FullName); var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); @@ -231,36 +231,37 @@ builder.Services.AddSwaggerGen(options => options.SwaggerDoc("Admin", new OpenApiInfo { Title = "API - Admin", Version = "v1" }); options.SwaggerDoc("Client", new OpenApiInfo { Title = "API - Client", Version = "v1" }); options.SwaggerDoc("Camera", new OpenApiInfo { Title = "API - Camera", Version = "v1" }); + options.SwaggerDoc("ProgramManager", new OpenApiInfo { Title = "API - ProgramManager", Version = "v1" }); options.DocInclusionPredicate((docName, apiDesc) => string.Equals(docName, apiDesc.GroupName, StringComparison.OrdinalIgnoreCase)); // اضافه کردن پشتیبانی از JWT در Swagger - options.AddSecurityDefinition("Bearer", new Microsoft.OpenApi.Models.OpenApiSecurityScheme - { - Name = "Authorization", - Type = Microsoft.OpenApi.Models.SecuritySchemeType.ApiKey, - Scheme = "Bearer", - BearerFormat = "JWT", - In = Microsoft.OpenApi.Models.ParameterLocation.Header, - Description = "لطفاً 'Bearer [space] token' را وارد کنید." - }); - - options.AddSecurityRequirement(new Microsoft.OpenApi.Models.OpenApiSecurityRequirement - { - { - new Microsoft.OpenApi.Models.OpenApiSecurityScheme - { - Reference = new Microsoft.OpenApi.Models.OpenApiReference - { - Type = Microsoft.OpenApi.Models.ReferenceType.SecurityScheme, - Id = "Bearer" - } - }, - Array.Empty() - } - }); + // options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme + // { + // Name = "Authorization", + // Type = SecuritySchemeType.ApiKey, + // Scheme = "Bearer", + // BearerFormat = "JWT", + // In = ParameterLocation.Header, + // Description = "لطفاً 'Bearer [space] token' را وارد کنید." + // }); + // + // options.AddSecurityRequirement(new OpenApiSecurityRequirement + // { + // { + // new Microsoft.OpenApi.Models.OpenApiSecurityScheme + // { + // Reference = new Microsoft.OpenApi.Models.OpenApiReference + // { + // Type = Microsoft.OpenApi.Models.ReferenceType.SecurityScheme, + // Id = "Bearer" + // } + // }, + // Array.Empty() + // } + // }); options.EnableAnnotations(); }); @@ -396,6 +397,8 @@ if (app.Environment.IsDevelopment()) options.SwaggerEndpoint("/swagger/Admin/swagger.json", "API - Admin"); options.SwaggerEndpoint("/swagger/Client/swagger.json", "API - Client"); options.SwaggerEndpoint("/swagger/Camera/swagger.json", "API - Camera"); + options.SwaggerEndpoint("/swagger/ProgramManager/swagger.json", "API - ProgramManager"); + }); } diff --git a/ServiceHost/ServiceHost.csproj b/ServiceHost/ServiceHost.csproj index 2c3be2d0..fe4fb60e 100644 --- a/ServiceHost/ServiceHost.csproj +++ b/ServiceHost/ServiceHost.csproj @@ -1,7 +1,7 @@  - net8.0 + net10.0 enable true @@ -69,6 +69,8 @@ + + @@ -77,25 +79,28 @@ - - - - - + + + + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + - - + + diff --git a/ServiceHost/appsettings.Development.json b/ServiceHost/appsettings.Development.json index b17b29c3..9fc1d34d 100644 --- a/ServiceHost/appsettings.Development.json +++ b/ServiceHost/appsettings.Development.json @@ -26,7 +26,8 @@ "TestDb": "Data Source=.;Initial Catalog=TestDb;Integrated Security=True;TrustServerCertificate=true;", //program_manager_db - "ProgramManagerDb": "Data Source=.;Initial Catalog=program_manager_db;Integrated Security=True;TrustServerCertificate=true;" + "ProgramManagerDb": "Data Source=.;Initial Catalog=program_manager_db;Integrated Security=True;TrustServerCertificate=true;", + "ProgramManagerDbServer": "Data Source=171.22.24.15;Initial Catalog=program_manager_db;Persist Security Info=False;User ID=ir_db;Password=R2rNp[170]18[3019]#@ATt;TrustServerCertificate=true;" //mahan Docker //"MesbahDb": "Data Source=localhost,5069;Initial Catalog=mesbah_db;User ID=sa;Password=YourPassword123;TrustServerCertificate=True;" }, diff --git a/Shared.Contracts/Holidays/HolidayDto.cs b/Shared.Contracts/Holidays/HolidayDto.cs new file mode 100644 index 00000000..7318b83e --- /dev/null +++ b/Shared.Contracts/Holidays/HolidayDto.cs @@ -0,0 +1,8 @@ +namespace Shared.Contracts.Holidays; + +public record HolidayDto +{ + public DateTime Holidaydate { get; private set; } + public long HolidayId { get; private set; } + public string HolidayYear { get; private set; } +} \ No newline at end of file diff --git a/Shared.Contracts/Holidays/IHolidayQueryService.cs b/Shared.Contracts/Holidays/IHolidayQueryService.cs new file mode 100644 index 00000000..8b41c745 --- /dev/null +++ b/Shared.Contracts/Holidays/IHolidayQueryService.cs @@ -0,0 +1,6 @@ +namespace Shared.Contracts.Holidays; + +public interface IHolidayQueryService +{ + Task> GetHolidaysInDates(DateTime startDate, DateTime endDate); +} \ No newline at end of file diff --git a/Shared.Contracts/PmRole/Commands/CreatePmRoleDto.cs b/Shared.Contracts/PmRole/Commands/CreatePmRoleDto.cs new file mode 100644 index 00000000..62edf3b6 --- /dev/null +++ b/Shared.Contracts/PmRole/Commands/CreatePmRoleDto.cs @@ -0,0 +1,9 @@ +namespace Shared.Contracts.PmRole.Commands; + +public record CreatePmRoleDto +{ + public string RoleName { get; set; } + public List Permissions { get; set; } + + public long? GozareshgirRoleId { get; set; } +}; \ No newline at end of file diff --git a/Shared.Contracts/PmRole/Commands/IPmRoleCommandService.cs b/Shared.Contracts/PmRole/Commands/IPmRoleCommandService.cs new file mode 100644 index 00000000..8be0cd83 --- /dev/null +++ b/Shared.Contracts/PmRole/Commands/IPmRoleCommandService.cs @@ -0,0 +1,7 @@ +namespace Shared.Contracts.PmRole.Commands; + +public interface IPmRoleCommandService +{ + Task<(bool, string)> Create(CreatePmRoleDto command); + Task<(bool, string)> Edit(CreatePmRoleDto command); +} \ No newline at end of file diff --git a/Shared.Contracts/PmRole/Queries/GetPmRolesDto.cs b/Shared.Contracts/PmRole/Queries/GetPmRolesDto.cs new file mode 100644 index 00000000..2bd131a2 --- /dev/null +++ b/Shared.Contracts/PmRole/Queries/GetPmRolesDto.cs @@ -0,0 +1,24 @@ +namespace Shared.Contracts.PmRole.Queries; + +public record GetPmRolesDto +{ + /// + /// آی دی نقش + /// + public long Id { get; set; } + + /// + /// نام نقش + /// + public string RoleName { get; set; } + + /// + /// آی دی نقش در گزارشگیر + /// + public long? GozareshgirRoleId { get; set; } + + /// + /// لیست کدهای دسترسی + /// + public List Permissions { get; set; } +}; \ No newline at end of file diff --git a/Shared.Contracts/PmRole/Queries/IPmRoleQueryService.cs b/Shared.Contracts/PmRole/Queries/IPmRoleQueryService.cs new file mode 100644 index 00000000..fef7ad2e --- /dev/null +++ b/Shared.Contracts/PmRole/Queries/IPmRoleQueryService.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Shared.Contracts.PmRole.Queries; + +public interface IPmRoleQueryService +{ + Task> GetPmRoleList(long? gozareshgirRoleId); +} + + diff --git a/Shared.Contracts/PmUser/IPmUserCommandService.cs b/Shared.Contracts/PmUser/IPmUserCommandService.cs new file mode 100644 index 00000000..193bcb71 --- /dev/null +++ b/Shared.Contracts/PmUser/IPmUserCommandService.cs @@ -0,0 +1,6 @@ +namespace Shared.Contracts.PmUser; + +public interface IPmUserCommandService +{ + Task<(bool isSuccess, string pmUserDto)> Create(); +} \ No newline at end of file diff --git a/Shared.Contracts/PmUser/IPmUserQueryService.cs b/Shared.Contracts/PmUser/IPmUserQueryService.cs new file mode 100644 index 00000000..479355de --- /dev/null +++ b/Shared.Contracts/PmUser/IPmUserQueryService.cs @@ -0,0 +1,6 @@ +namespace Shared.Contracts.PmUser; + +public interface IPmUserQueryService +{ + Task GetCurrentPmUserIdFromAccountId(long accountId); +} \ No newline at end of file diff --git a/Shared.Contracts/Shared.Contracts.csproj b/Shared.Contracts/Shared.Contracts.csproj new file mode 100644 index 00000000..237d6616 --- /dev/null +++ b/Shared.Contracts/Shared.Contracts.csproj @@ -0,0 +1,9 @@ + + + + net10.0 + enable + enable + + + diff --git a/WorkFlow/Application/WorkFlow.Application.Contracts/WorkFlow.Application.Contracts.csproj b/WorkFlow/Application/WorkFlow.Application.Contracts/WorkFlow.Application.Contracts.csproj index 62f2add8..6801f518 100644 --- a/WorkFlow/Application/WorkFlow.Application.Contracts/WorkFlow.Application.Contracts.csproj +++ b/WorkFlow/Application/WorkFlow.Application.Contracts/WorkFlow.Application.Contracts.csproj @@ -1,11 +1,18 @@  - net8.0 + net10.0 enable enable + + + + + + + diff --git a/WorkFlow/Application/WorkFlow.Application/WorkFlow.Application.csproj b/WorkFlow/Application/WorkFlow.Application/WorkFlow.Application.csproj index 231fd693..00eb5cf6 100644 --- a/WorkFlow/Application/WorkFlow.Application/WorkFlow.Application.csproj +++ b/WorkFlow/Application/WorkFlow.Application/WorkFlow.Application.csproj @@ -1,11 +1,18 @@  - net8.0 + net10.0 enable enable + + + + + + + diff --git a/WorkFlow/Domain/WorkFlow.Domain/WorkFlow.Domain.csproj b/WorkFlow/Domain/WorkFlow.Domain/WorkFlow.Domain.csproj index 242d5353..c22ace88 100644 --- a/WorkFlow/Domain/WorkFlow.Domain/WorkFlow.Domain.csproj +++ b/WorkFlow/Domain/WorkFlow.Domain/WorkFlow.Domain.csproj @@ -1,11 +1,18 @@  - net8.0 + net10.0 enable enable + + + + + + + diff --git a/WorkFlow/Infrastructure/WorkFlow.Infrastructure.ACL/WorkFlow.Infrastructure.ACL.csproj b/WorkFlow/Infrastructure/WorkFlow.Infrastructure.ACL/WorkFlow.Infrastructure.ACL.csproj index ed7e9ba4..3d1e8b51 100644 --- a/WorkFlow/Infrastructure/WorkFlow.Infrastructure.ACL/WorkFlow.Infrastructure.ACL.csproj +++ b/WorkFlow/Infrastructure/WorkFlow.Infrastructure.ACL/WorkFlow.Infrastructure.ACL.csproj @@ -1,11 +1,18 @@  - net8.0 + net10.0 enable enable + + + + + + + diff --git a/WorkFlow/Infrastructure/WorkFlow.Infrastructure.Config/WorkFlow.Infrastructure.Config.csproj b/WorkFlow/Infrastructure/WorkFlow.Infrastructure.Config/WorkFlow.Infrastructure.Config.csproj index 0fe5e5ec..be68564a 100644 --- a/WorkFlow/Infrastructure/WorkFlow.Infrastructure.Config/WorkFlow.Infrastructure.Config.csproj +++ b/WorkFlow/Infrastructure/WorkFlow.Infrastructure.Config/WorkFlow.Infrastructure.Config.csproj @@ -1,12 +1,14 @@  - net8.0 + net10.0 enable enable - + + + diff --git a/WorkFlow/Infrastructure/WorkFlow.Infrastructure.EfCore/WorkFlow.Infrastructure.EfCore.csproj b/WorkFlow/Infrastructure/WorkFlow.Infrastructure.EfCore/WorkFlow.Infrastructure.EfCore.csproj index de6a663d..20fa980a 100644 --- a/WorkFlow/Infrastructure/WorkFlow.Infrastructure.EfCore/WorkFlow.Infrastructure.EfCore.csproj +++ b/WorkFlow/Infrastructure/WorkFlow.Infrastructure.EfCore/WorkFlow.Infrastructure.EfCore.csproj @@ -1,18 +1,23 @@  - net8.0 + net10.0 enable enable - - - + + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive + + diff --git a/_0_Framework/_0_Framework_b.csproj b/_0_Framework/_0_Framework_b.csproj index bb6a3bd7..7f4e6b3d 100644 --- a/_0_Framework/_0_Framework_b.csproj +++ b/_0_Framework/_0_Framework_b.csproj @@ -1,15 +1,16 @@ - net8.0 + net10.0 - - - - - + + + + + + diff --git a/backService/backService.csproj b/backService/backService.csproj index eb699246..848d38c6 100644 --- a/backService/backService.csproj +++ b/backService/backService.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0