Commit 0f8a3073 authored by hasan khaddour's avatar hasan khaddour

Fix s

parent a946c6cb
......@@ -19,6 +19,7 @@ namespace PSManagement.Infrastructure.Persistence
}
public DbSet<ParticipationChange> ParticipationChanges { get; set; }
public DbSet<User> Users { get; set; }
public DbSet<Role> Roles { get; set; }
public DbSet<Permission> Permission { get; set; }
......@@ -42,8 +43,7 @@ namespace PSManagement.Infrastructure.Persistence
{
modelBuilder.ApplyConfigurationsFromAssembly(typeof(AppDbContext).Assembly);
// modelBuilder.Entity<BaseEntity>().Ignore(e => e.Events);
SeedData.SeedAsync(modelBuilder).Wait();
base.OnModelCreating(modelBuilder);
......
......@@ -27,10 +27,39 @@ namespace PSManagement.Infrastructure.Persistence.DI
public static IServiceCollection AddPersistence(this IServiceCollection services, IConfiguration configuration)
{
services.AddDbContext<AppDbContext>(options => {
options.UseSqlServer(configuration.GetConnectionString("DefaultConnection"));
});
services
.AddBuilders()
.AddDataContext(configuration)
.AddRepositories()
.AddUOW();
return services;
}
#region Register Builders
private static IServiceCollection AddBuilders(this IServiceCollection services)
{
services.AddScoped<ProjectBuilder>();
return services;
}
#endregion Register Builders
#region Register UOW
private static IServiceCollection AddUOW(this IServiceCollection services) {
services.AddScoped<IUnitOfWork, UnitOfWork>();
return services;
}
#endregion Register UOW
#region Register Repositories
private static IServiceCollection AddRepositories(this IServiceCollection services) {
services.AddScoped(typeof(IRepository<>), typeof(BaseRepository<>));
services.AddScoped<IUsersRepository, UsersRepository>();
services.AddScoped<ICustomersRepository, CustomersReposiotry>();
services.AddScoped<IProjectsRepository, ProjectsRepository>();
......@@ -41,12 +70,23 @@ namespace PSManagement.Infrastructure.Persistence.DI
services.AddScoped<ITracksRepository, TracksRepository>();
services.AddScoped<IProjectTypesRepository, ProjectsTypesRepository>();
services.AddScoped<ProjectBuilder>();
services.AddScoped(typeof(IRepository<>), typeof(BaseRepository<>));
services.AddScoped<IUnitOfWork, UnitOfWork>();
return services;
}
#endregion Register Repositoryies
#region Register Data context
private static IServiceCollection AddDataContext(this IServiceCollection services ,IConfiguration configuration) {
services.AddDbContext<AppDbContext>(options => {
options.UseSqlServer(configuration.GetConnectionString("DefaultConnection"));
});
return services;
}
#endregion Register Data Context
}
}
......@@ -97,6 +97,21 @@ namespace PSManagement.Infrastructure.Persistence.EntitiesConfiguration
;
}
}
public class participationChangesConfiguration : IEntityTypeConfiguration<ParticipationChange>
{
public void Configure(EntityTypeBuilder<ParticipationChange> builder)
{
builder
.HasOne(e => e.Employee)
.WithOne();
builder
.HasOne(e => e.Project)
.WithOne()
;
}
}
}
using Microsoft.EntityFrameworkCore.Migrations;
namespace PSManagement.Infrastructure.Persistence.Migrations
{
public partial class AddProjectTypeDetails : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "StepInfo_NumberOfWorker",
table: "Steps",
type: "int",
nullable: true);
migrationBuilder.AddColumn<int>(
name: "ExpectedNumberOfWorker",
table: "ProjectType",
type: "int",
nullable: false,
defaultValue: 0);
migrationBuilder.InsertData(
table: "Roles",
columns: new[] { "Id", "Name" },
values: new object[] { 5, "Planner" });
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DeleteData(
table: "Roles",
keyColumn: "Id",
keyValue: 5);
migrationBuilder.DropColumn(
name: "StepInfo_NumberOfWorker",
table: "Steps");
migrationBuilder.DropColumn(
name: "ExpectedNumberOfWorker",
table: "ProjectType");
}
}
}
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace PSManagement.Infrastructure.Persistence.Migrations
{
public partial class AddParticipationHistory : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "ParticipationChanges",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
EmployeeId = table.Column<int>(type: "int", nullable: false),
ProjectId = table.Column<int>(type: "int", nullable: false),
PartialTimeBefore = table.Column<int>(type: "int", nullable: false),
PartialTimeAfter = table.Column<int>(type: "int", nullable: false),
RoleBefore = table.Column<string>(type: "nvarchar(max)", nullable: true),
RoleAfter = table.Column<string>(type: "nvarchar(max)", nullable: true),
ChangeDate = table.Column<DateTime>(type: "datetime2", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ParticipationChanges", x => x.Id);
table.ForeignKey(
name: "FK_ParticipationChanges_Employees_EmployeeId",
column: x => x.EmployeeId,
principalTable: "Employees",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_ParticipationChanges_Projects_ProjectId",
column: x => x.ProjectId,
principalTable: "Projects",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_ParticipationChanges_EmployeeId",
table: "ParticipationChanges",
column: "EmployeeId",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_ParticipationChanges_ProjectId",
table: "ParticipationChanges",
column: "ProjectId",
unique: true);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "ParticipationChanges");
}
}
}
......@@ -207,6 +207,11 @@ namespace PSManagement.Infrastructure.Persistence.Migrations
{
Id = 4,
Name = "Scientific-Deputy"
},
new
{
Id = 5,
Name = "Planner"
});
});
......@@ -294,6 +299,45 @@ namespace PSManagement.Infrastructure.Persistence.Migrations
b.ToTable("EmployeeParticipate");
});
modelBuilder.Entity("PSManagement.Domain.Projects.Entities.ParticipationChange", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<DateTime>("ChangeDate")
.HasColumnType("datetime2");
b.Property<int>("EmployeeId")
.HasColumnType("int");
b.Property<int>("PartialTimeAfter")
.HasColumnType("int");
b.Property<int>("PartialTimeBefore")
.HasColumnType("int");
b.Property<int>("ProjectId")
.HasColumnType("int");
b.Property<string>("RoleAfter")
.HasColumnType("nvarchar(max)");
b.Property<string>("RoleBefore")
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.HasIndex("EmployeeId")
.IsUnique();
b.HasIndex("ProjectId")
.IsUnique();
b.ToTable("ParticipationChanges");
});
modelBuilder.Entity("PSManagement.Domain.Projects.Entities.Project", b =>
{
b.Property<int>("Id")
......@@ -373,48 +417,51 @@ namespace PSManagement.Infrastructure.Persistence.Migrations
b.ToTable("ProjectCompletion");
});
modelBuilder.Entity("PSManagement.Domain.Projects.Entities.ProjectType", b =>
modelBuilder.Entity("PSManagement.Domain.Projects.Entities.Step", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("Description")
.HasColumnType("nvarchar(max)");
b.Property<int>("CurrentCompletionRatio")
.HasColumnType("int");
b.Property<int>("ExpectedEffort")
b.Property<int>("ProjectId")
.HasColumnType("int");
b.Property<string>("TypeName")
.HasColumnType("nvarchar(max)");
b.Property<int>("Weight")
.HasColumnType("int");
b.HasKey("Id");
b.ToTable("ProjectType");
b.HasIndex("ProjectId");
b.ToTable("Steps");
});
modelBuilder.Entity("PSManagement.Domain.Projects.Entities.Step", b =>
modelBuilder.Entity("PSManagement.Domain.ProjectsTypes.Entites.ProjectType", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<int>("CurrentCompletionRatio")
.HasColumnType("int");
b.Property<string>("Description")
.HasColumnType("nvarchar(max)");
b.Property<int>("ProjectId")
b.Property<int>("ExpectedEffort")
.HasColumnType("int");
b.Property<int>("Weight")
b.Property<int>("ExpectedNumberOfWorker")
.HasColumnType("int");
b.HasKey("Id");
b.Property<string>("TypeName")
.HasColumnType("nvarchar(max)");
b.HasIndex("ProjectId");
b.HasKey("Id");
b.ToTable("Steps");
b.ToTable("ProjectType");
});
modelBuilder.Entity("PSManagement.Domain.Tracking.EmployeeTrack", b =>
......@@ -726,6 +773,25 @@ namespace PSManagement.Infrastructure.Persistence.Migrations
b.Navigation("Project");
});
modelBuilder.Entity("PSManagement.Domain.Projects.Entities.ParticipationChange", b =>
{
b.HasOne("PSManagement.Domain.Employees.Entities.Employee", "Employee")
.WithOne()
.HasForeignKey("PSManagement.Domain.Projects.Entities.ParticipationChange", "EmployeeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("PSManagement.Domain.Projects.Entities.Project", "Project")
.WithOne()
.HasForeignKey("PSManagement.Domain.Projects.Entities.ParticipationChange", "ProjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Employee");
b.Navigation("Project");
});
modelBuilder.Entity("PSManagement.Domain.Projects.Entities.Project", b =>
{
b.HasOne("PSManagement.Domain.Customers.Entities.Customer", null)
......@@ -743,13 +809,13 @@ namespace PSManagement.Infrastructure.Persistence.Migrations
.HasForeignKey("ProjectManagerId")
.OnDelete(DeleteBehavior.Restrict);
b.HasOne("PSManagement.Domain.Projects.Entities.ProjectType", "ProjectType")
b.HasOne("PSManagement.Domain.ProjectsTypes.Entites.ProjectType", "ProjectType")
.WithMany()
.HasForeignKey("ProjectTypeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("PSManagement.Domain.Projects.Entities.ProjectType", null)
b.HasOne("PSManagement.Domain.ProjectsTypes.Entites.ProjectType", null)
.WithMany("Projects")
.HasForeignKey("ProjectTypeId1");
......@@ -946,6 +1012,9 @@ namespace PSManagement.Infrastructure.Persistence.Migrations
.HasColumnType("int")
.HasColumnName("Duration");
b1.Property<int>("NumberOfWorker")
.HasColumnType("int");
b1.Property<DateTime>("StartDate")
.HasColumnType("datetime2")
.HasColumnName("StartDate");
......@@ -1169,14 +1238,14 @@ namespace PSManagement.Infrastructure.Persistence.Migrations
b.Navigation("Tracks");
});
modelBuilder.Entity("PSManagement.Domain.Projects.Entities.ProjectType", b =>
modelBuilder.Entity("PSManagement.Domain.Projects.Entities.Step", b =>
{
b.Navigation("Projects");
b.Navigation("StepTracks");
});
modelBuilder.Entity("PSManagement.Domain.Projects.Entities.Step", b =>
modelBuilder.Entity("PSManagement.Domain.ProjectsTypes.Entites.ProjectType", b =>
{
b.Navigation("StepTracks");
b.Navigation("Projects");
});
modelBuilder.Entity("PSManagement.Domain.Tracking.Track", b =>
......
using Microsoft.EntityFrameworkCore;
using PSManagement.Domain.Projects.Entities;
using PSManagement.Domain.Projects.Repositories;
using PSManagement.Domain.ProjectsTypes.Entites;
using PSManagement.Infrastructure.Persistence.Repositories.Base;
using PSManagement.SharedKernel.Interfaces;
using System.Collections.Generic;
......
......@@ -19,6 +19,8 @@ namespace PSManagement.Infrastructure.Persistence.SeedDataContext
SeedRoles(builder);
return Task.CompletedTask;
}
#region Configure Departments
public static void SeedDepartments(ModelBuilder builder) {
builder.Entity<Department>().HasData(
......@@ -33,17 +35,25 @@ namespace PSManagement.Infrastructure.Persistence.SeedDataContext
) ;
}
#endregion Configure Departments
#region Seed Roles
public static void SeedRoles(ModelBuilder builder)
{
builder.Entity<Role>().HasData(
new Role {Id=1, Name = "Admin" },
new Role {Id = 2, Name = "Employee" },
new Role {Id = 4, Name = "Scientific-Deputy" }
new Role {Id = 4, Name = "Scientific-Deputy" },
new Role { Id = 5, Name = "Planner" }
);
}
#endregion Seed Roles
#region Configure Admin
public static void SeedAdmin(ModelBuilder builder)
{
......@@ -56,5 +66,7 @@ namespace PSManagement.Infrastructure.Persistence.SeedDataContext
);
}
#endregion Configure Admin
}
}
......@@ -13,54 +13,84 @@ namespace PSManagement.Infrastructure.Persistence.UoW
{
public class UnitOfWork :IUnitOfWork
{
#region Dependencies
private readonly AppDbContext _dbContext;
private readonly IMediator _mediator;
#endregion Dependencies
#region Constructor
public UnitOfWork(AppDbContext dbContext, IMediator mediator)
{
_dbContext = dbContext;
_mediator = mediator;
}
#endregion Constructor
public async Task SaveChangesAsync(CancellationToken cancellationToken = default)
{
await DispatchEventsAsync();
await _dbContext.SaveChangesAsync(cancellationToken);
}
#region Process Events
private async Task DispatchEventsAsync()
{
// list for the processed event
var processedDomainEvents = new List<IDomainEvent>();
// list of un processed events
var unprocessedDomainEvents = GetDomainEvents().AsEnumerable();
// this is needed incase another DomainEvent is published from a DomainEventHandler
while (unprocessedDomainEvents.Any())
{
// publish domain events
await DispatchDomainEventsAsync(unprocessedDomainEvents);
// move the un processed to the processed
processedDomainEvents.AddRange(unprocessedDomainEvents);
// get the newest un processed events
unprocessedDomainEvents = GetDomainEvents()
.Where(e => !processedDomainEvents.Contains(e))
.ToList();
}
// clear the events
ClearDomainEvents();
}
#endregion Process Events
#region Get Events
private List<IDomainEvent> GetDomainEvents()
{
// change tracker to the base entity
var aggregateRoots = GetTrackedEntites();
// get the events list
return aggregateRoots
.SelectMany(x => x.Events)
.ToList();
}
#endregion Get Events
#region Get Tracked
private List<BaseEntity> GetTrackedEntites()
{
// change tracker to the base enties that has an events
return _dbContext.ChangeTracker
.Entries<BaseEntity>()
.Where(x => x.Entity.Events != null && x.Entity.Events.Any())
.Select(e => e.Entity)
.ToList();
}
#endregion Get Tracked
#region Dispatch Events
private async Task DispatchDomainEventsAsync(IEnumerable<IDomainEvent> domainEvents)
{
foreach (var domainEvent in domainEvents)
......@@ -69,6 +99,9 @@ namespace PSManagement.Infrastructure.Persistence.UoW
}
}
#endregion Dispatch Events
#region Clear And Dispose
private void ClearDomainEvents()
{
var aggregateRoots = GetTrackedEntites();
......@@ -79,6 +112,6 @@ namespace PSManagement.Infrastructure.Persistence.UoW
{
_dbContext.Dispose();
}
#endregion Clear And Dispose
}
}
......@@ -20,7 +20,11 @@ namespace PSManagement.Infrastructure.Services.Authentication
private readonly IUsersRepository _userRepository;
private readonly BaseSpecification<User> _specification;
private readonly IMapper _mapper;
public AuthenticationService(IJwtTokenGenerator jwtTokenGenerator, IUsersRepository userRepository, IMapper mapper)
public AuthenticationService(
IJwtTokenGenerator jwtTokenGenerator,
IUsersRepository userRepository,
IMapper mapper
)
{
_jwtTokenGenerator = jwtTokenGenerator;
_userRepository = userRepository;
......@@ -28,15 +32,21 @@ namespace PSManagement.Infrastructure.Services.Authentication
_mapper = mapper;
}
#region Login
public async Task<Result<AuthenticationResult>> Login(String email, String password) {
_specification.AddInclude(e => e.Employee);
_specification.AddInclude(e=> e.Roles);
User u = await _userRepository.GetByEmail(email,_specification);
if (u is null || u.HashedPassword != password) {
if (u is null || u.HashedPassword != hashPassword(password)) {
return Result.Invalid(UserErrors.InvalidLoginAttempt);
}
String token = _jwtTokenGenerator.GenerateToken(u);
return new AuthenticationResult {
......@@ -47,12 +57,18 @@ namespace PSManagement.Infrastructure.Services.Authentication
Roles=_mapper.Map<ICollection<RoleDTO>>(u.Roles),
Token=token};
}
#endregion Login
#region Registeration
public async Task<Result<AuthenticationResult>> Register(String email, String userName, String password) {
// check if the user exist
var u = await _userRepository.GetByEmail(email);
if (u is not null) {
return Result.Invalid(UserErrors.AlreadyUserExist);
}
var user = await _userRepository.AddAsync(
new User{
Email=email ,
......@@ -74,6 +90,14 @@ namespace PSManagement.Infrastructure.Services.Authentication
}
#endregion Registeration
#region Password Hasher
private string hashPassword(string passsword) {
return passsword;
}
#endregion Password Hasher
}
......
......@@ -37,6 +37,8 @@ namespace PSManagement.Infrastructure.DI
return services;
}
#region Add Servcies
private static IServiceCollection AddServices(this IServiceCollection services, IConfiguration configuration)
{
services.Configure<FileServiceSettings>(configuration.GetSection(FileServiceSettings.SectionName));
......@@ -49,9 +51,13 @@ namespace PSManagement.Infrastructure.DI
services.AddScoped<IEmailService,EmailService>();
return services;
}
#endregion Add Servcies
#region Background jobs
private static IServiceCollection AddBackgroundServices(this IServiceCollection services,IConfiguration configuration)
{
services.Configure<EmployeesSyncJobSettings>(configuration.GetSection("EmpoyeesSyncJobSettings"));
services.Configure<EmployeesSyncJobSettings>(configuration.GetSection(EmployeesSyncJobSettings.SectionName));
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddScoped<ISyncEmployeesService, SyncEmployeesService>();
......@@ -61,7 +67,9 @@ namespace PSManagement.Infrastructure.DI
return services;
}
#endregion Background jobs
#region Authorization
private static IServiceCollection AddAuthorization(this IServiceCollection services)
{
services.AddScoped<IUserRoleService, UserRolesService>();
......@@ -69,7 +77,9 @@ namespace PSManagement.Infrastructure.DI
return services;
}
#endregion Authorization
#region Authentication
private static IServiceCollection AddAuthentication(this IServiceCollection services, IConfiguration configuration)
{
services.Configure<JwtSetting>(configuration.GetSection(JwtSetting.Section));
......@@ -84,5 +94,6 @@ namespace PSManagement.Infrastructure.DI
return services;
}
#endregion Authentication
}
}
......@@ -2,6 +2,7 @@
{
public class EmployeesSyncJobSettings
{
public const string SectionName = "EmpoyeesSyncJobSettings";
public int SyncIntervalInMinutes { get; set; }
}
}
......@@ -44,11 +44,15 @@ namespace PSManagement.Infrastructure.BackgroundServcies
public async Task<SyncResponse> SyncEmployees(IEmployeesProvider employeesProvider)
{
IEnumerable<Employee> NewestEmployees = await _employeesProviders.FetchEmployees();
int count = 0;
foreach (Employee employee in NewestEmployees) {
_specification.Criteria = empl => empl.HIASTId == employee.HIASTId;
Employee emp = _employeesRepository.ListAsync(_specification).Result.FirstOrDefault();
if (emp is null) {
emp =await _employeesRepository.AddAsync(employee);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment