Skip to content

Commit

Permalink
1
Browse files Browse the repository at this point in the history
  • Loading branch information
akbaramd committed Jan 2, 2025
1 parent 02bf7f1 commit 3a70cd3
Show file tree
Hide file tree
Showing 34 changed files with 984 additions and 215 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using Nezam.EEs.Shared.Domain.Identity.User.ValueObjects;
using Payeh.SharedKernel.Domain.DomainEvents;

namespace Nezam.EEs.Shared.Domain.Identity.User.DomainEvents
{
public class DepartmentCreatedEvent : DomainEvent
{
public DepartmentId DepartmentId { get; }
public string Title { get; }

public DepartmentCreatedEvent(DepartmentId userId, string title)
{
DepartmentId = userId;
Title = title;
}
}
}
8 changes: 8 additions & 0 deletions Nezam.EES.Shared/Domain/Identity/User/DepartmentId.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using Payeh.SharedKernel.Domain.ValueObjects;

namespace Nezam.EEs.Shared.Domain.Identity.User;

public class DepartmentId : GuidBusinessId<DepartmentId>
{

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Nezam.EEs.Shared.Domain.Identity.User.ValueObjects;
using Payeh.SharedKernel.Domain.DomainEvents;

namespace Nezam.EEs.Shared.Domain.Identity.User.DomainEvents;

public class UserDepartmentUpdatedEvent : DomainEvent
{
public UserId UserId { get; }
public DepartmentId[] Departments { get; }

public UserDepartmentUpdatedEvent(UserId userId, DepartmentId[] departments)
{
UserId = userId;
Departments = departments;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Nezam.EEs.Shared.Domain.Identity.User.ValueObjects;
using Payeh.SharedKernel.Domain.DomainEvents;

namespace Nezam.EEs.Shared.Domain.Identity.User.DomainEvents;

public class UserRoleUpdatedEvent : DomainEvent
{
public UserId UserId { get; }
public string[] Roles { get; }

public UserRoleUpdatedEvent(UserId userId, string[] roles)
{
UserId = userId;
Roles = roles;
}
}
4 changes: 0 additions & 4 deletions Nezam.EES.Shared/Nezam.EES.Shared.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,4 @@
<ProjectReference Include="..\New\Payeh.SharedKernel\Payeh.SharedKernel.csproj" />
</ItemGroup>

<ItemGroup>
<Folder Include="Domain\Identity\" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,20 @@ public override async Task HandleAsync(AuthLoginRequest req, CancellationToken c
return;
}

var claims = new[]
{
new Claim(ClaimTypes.Name, user.Data.UserName.Value),
new Claim(ClaimTypes.NameIdentifier, user.Data.UserId.Value.ToString())

}.ToList();

claims.AddRange(user.Data.Roles.Select(x => new Claim(ClaimTypes.Role, x.RoleId.Value)));

var token = JWTBearer.CreateToken(
signingKey: _configuration["Jwt:SecretKey"],
expireAt: DateTime.UtcNow.AddHours(1),
claims: new[]
{
new Claim(ClaimTypes.Name, user.Data.UserName.Value),
new Claim(ClaimTypes.NameIdentifier, user.Data.UserId.Value.ToString())
});
claims: claims,
roles:user.Data.Roles.Select(x=>x.RoleId.Value));

await SendAsync(new AuthLoginResponse { AccessToken = token }, cancellation: ct);
await uow.CommitAsync(ct);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
using Microsoft.EntityFrameworkCore;
using Nezam.EES.Service.Identity.Application.Dto.Users;
using Nezam.EES.Service.Identity.Infrastructure.EntityFrameworkCore;
using System.Linq.Dynamic.Core;
using Nezam.EEs.Shared.Domain.Identity.User;
using Nezam.EEs.Shared.Domain.Identity.User.ValueObjects;

namespace Nezam.EES.Service.Identity.Application.UseCases.Users.GetUsers;

Expand All @@ -21,38 +24,102 @@ public override void Configure()
AllowAnonymous();
}

public override async Task HandleAsync(GetUsersRequest req, CancellationToken ct)
public override async Task HandleAsync(GetUsersRequest req, CancellationToken ct)
{
// Step 1: Prepare the query
var query = _dbContext.Users.Include(x => x.Roles).AsNoTracking();

// Step 2: Apply filters
if (req.Filters != null && req.Filters.Any())
{
// Step 1: Prepare the query
var query = _dbContext.Users.Include(x=>x.Roles).AsNoTracking();
var sections= req.Filters.Split(',');
foreach (var filter in sections)
{
var parts = filter.Split(':');
if (parts.Length == 2)
{
var propertyPath = parts[0];
var value = parts[1];

// Step 2: Apply search filter if provided
if (!string.IsNullOrWhiteSpace(req.Search))
switch (propertyPath)
{
case "UserName":
query = query.Where(c => c.UserName == UserNameId.NewId(value));
break;
case "Email":
query = query.Where(c => c.Email != null && c.Email.Value == value);
break;
case "FirstName":
query = query.Where(c => c.Profile != null && c.Profile.FirstName.Contains(value));
break;
case "LastName":
query = query.Where(c => c.Profile != null && c.Profile.LastName.Contains(value));
break;
}
}
}
}

// Step 3: Apply sorting
if (!string.IsNullOrWhiteSpace(req.Sorting))
{
var sortingParts = req.Sorting.Split(':');
if (sortingParts.Length == 2)
{
string searchTerm = req.Search.Trim();
query = query.Where(u =>
u.IsSoftDeleted == false &&
u.Email != null &&
(u.UserName.Value.Contains(searchTerm) || u.Email.Value.Contains(searchTerm)));
var propertyPath = sortingParts[0];
var direction = sortingParts[1].ToLower();

switch (propertyPath)
{
case "UserName":
query = direction == "desc"
? query.OrderByDescending(u => u.UserName.Value)
: query.OrderBy(u => u.UserName.Value);
break;
case "Email":
query = direction == "desc"
? query.OrderByDescending(u => u.Email.Value)
: query.OrderBy(u => u.Email.Value);
break;
case "FirstName":
query = direction == "desc"
? query.OrderByDescending(u => u.Profile.FirstName)
: query.OrderBy(u => u.Profile.FirstName);
break;
case "LastName":
query = direction == "desc"
? query.OrderByDescending(u => u.Profile.LastName)
: query.OrderBy(u => u.Profile.LastName);
break;
default:
throw new ArgumentException($"Unsupported sorting property: {propertyPath}");
}
}
}
else
{
// Default sorting
query = query.OrderBy(u => u.Email.Value);
}

// Step 3: Get total count for pagination
int totalCount = await query.CountAsync(ct);
// Step 4: Get total count for pagination
int totalCount = await query.CountAsync(ct);

// Step 4: Fetch the data with pagination and map to DTO
var users = await query
.Skip(req.Skip)
.Take(req.Take)
.ToListAsync(ct);
// Step 5: Fetch the data with pagination and map to DTO
var users = await query
.Skip(req.Skip)
.Take(req.Take)
.ToListAsync(ct);

var userDtos = users.Select(UserDto.FromEntity).ToList();

// Step 6: Return the response
await SendAsync(new GetUsersResponse
{
Results = userDtos,
TotalCount = totalCount
}, cancellation: ct);
}

// Map entities to DTOs using the FromEntity method
var userDtos = users.Select(UserDto.FromEntity).ToList();

// Step 5: Return the response
await SendAsync(new GetUsersResponse
{
Results = userDtos,
TotalCount = totalCount
}, cancellation: ct);
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,23 @@
using Nezam.EES.Service.Identity.Application.Dto;
using Nezam.EEs.Shared.Application.Dto;
using System.Collections.Generic;

namespace Nezam.EES.Service.Identity.Application.UseCases.Users.GetUsers;

/// <summary>
/// Request class for fetching users with support for pagination, filtering, and sorting.
/// </summary>
public class GetUsersRequest : PaginatedRequest
{
/// <summary>
/// Filters to apply on the user data. Each filter is a string in the format "Property:Value".
/// Example: "Profile.LastName:Smith,Email.Value:test".
/// </summary>
public string? Filters { get; set; }

/// <summary>
/// Sorting instructions in the format "Property:Direction".
/// Example: "Email.Value:asc".
/// </summary>
public string? Sorting { get; set; }
}
51 changes: 51 additions & 0 deletions Nezam.EES.Slice.Identity/Domains/Departments/DepartmentEntity.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using Nezam.EES.Service.Identity.Domains.Users;
using Nezam.EEs.Shared.Domain.Identity.User;
using Nezam.EEs.Shared.Domain.Identity.User.DomainEvents;
using Payeh.SharedKernel.Domain;

namespace Nezam.EES.Service.Identity.Domains.Departments
{
public class DepartmentEntity : AggregateRoot
{
// Protected constructor for EF Core
protected DepartmentEntity()
{
}

public DepartmentEntity(DepartmentId departmentId, string title) : this()
{
DepartmentId = departmentId;
SetTitle(title);
AddDomainEvent(new DepartmentCreatedEvent(departmentId,title));

}

public DepartmentId DepartmentId { get; private set; }
public string Title { get; private set; }

public ICollection<UserEntity> Users { get; private set; }

// Method to update title
public void SetTitle(string title)
{
if (string.IsNullOrWhiteSpace(title))
{
throw new ArgumentException("Title cannot be empty", nameof(title));
}

if (title.Length > 50)
{
throw new ArgumentException("Title cannot exceed 50 characters", nameof(title));
}

Title = title;
}

// Override to provide unique key for this entity
public override object GetKey()
{
return DepartmentId;
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using Payeh.SharedKernel.Domain.Repositories;

namespace Nezam.EES.Service.Identity.Domains.Departments.Repositories;

public interface IDepartmentRepository : IRepository<DepartmentEntity>
{

}
Loading

0 comments on commit 3a70cd3

Please sign in to comment.