Skip to content

Commit

Permalink
1
Browse files Browse the repository at this point in the history
  • Loading branch information
akbaramd committed Dec 30, 2024
1 parent 9291575 commit 6ecd150
Show file tree
Hide file tree
Showing 20 changed files with 456 additions and 26 deletions.
2 changes: 2 additions & 0 deletions New/Payeh.SharedKernel/UnitOfWork/UnitOfWork.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ public async Task CommitAsync(CancellationToken cancellationToken = default)
}

await PublishDomainEventsAsync();

Dispose();
}
catch
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public UserEmailValue(string email)
}

// Check if the email format is valid
private bool IsValidEmail(string email)
public static bool IsValidEmail(string email)
{
var emailRegex = new Regex(@"^[^@]+@[^@]+\.[^@]+$");
return emailRegex.IsMatch(email);
Expand Down
3 changes: 2 additions & 1 deletion Nezam.EES.Slice.Identity/Application/Dto/Users/UserDto.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public class UserDto
public UserEmailValue? Email { get; set; }
public UserProfileValue Profile { get; set; } // Optional profile info
public List<RoleDto> Roles { get; set; } // Optional profile info

public bool IsCanDelete { get; set; }
// Static method for mapping UserEntity to UserDto
public static UserDto FromEntity(UserEntity user)
{
Expand All @@ -22,6 +22,7 @@ public static UserDto FromEntity(UserEntity user)
UserName = user.UserName, // Assuming UserName is a value object
Email = user.Email, // Assuming Email is a value object
Profile = user.Profile,
IsCanDelete = user.IsCanDelete,
Roles = user.Roles.Select(x => RoleDto.FromEntity(x)).ToList()
};
}
Expand Down
13 changes: 11 additions & 2 deletions Nezam.EES.Slice.Identity/Domains/Users/UserEntity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public class UserEntity : AggregateRoot
public UserProfileValue? Profile { get; private set; }
public ICollection<UserTokenEntity> Tokens { get; private set; } = [];

public bool IsCanDelete { get; private set; } = true;
public bool IsSoftDeleted { get; private set; } = false;

// Collection to hold assigned roles
Expand All @@ -31,8 +32,9 @@ public UserEntity(UserId userId, UserNameId userName, UserPasswordValue password
Email = email;
Tokens = new List<UserTokenEntity>(); // Initialize the token collection
Roles = new List<RoleEntity>(); // Initialize the roles collection

CanDelete();
AddDomainEvent(new UserCreatedEvent(userId, userName.Value, email?.Value, profile));

}

// Method for changing the username
Expand Down Expand Up @@ -93,7 +95,14 @@ public void SoftDelete()
IsSoftDeleted = true;
}


public void CanDelete()
{
IsCanDelete = true;
}
public void CanNotDelete()
{
IsCanDelete = false;
}
// Method to check if the user has a specific role
public bool HasRole(RoleEntity role)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
var user = find.Data;
user.UpdateProfile(new UserProfileValue( "admin", "administrator"));
user.CanNotDelete();
await domainService.UpdateAsync(user);

await domainService.AssignRoleAsync(user, [roleId]);
Expand Down
52 changes: 51 additions & 1 deletion Nezam.EES.Slice.Secretariat/Application/Dto/DocumentDto.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ public class DocumentDto
public DocumentId DocumentId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public string TrackingCode { get; set; }
public int LetterNumber { get; set; }
public DateTime LetterDate { get; set; }
public DocumentType Type { get; set; }
public DocumentStatus Status { get; set; }
public ParticipantDto Owner { get; set; }
Expand All @@ -23,6 +26,9 @@ public static DocumentDto FromEntity(DocumentAggregateRoot document)
{
DocumentId = document.DocumentId,
Title = document.Title,
TrackingCode = document.TrackingCode,
LetterNumber = document.LetterNumber,
LetterDate = document.LetterDate,
Content = document.Content,
Type = document.Type,
Status = document.Status,
Expand Down Expand Up @@ -62,10 +68,54 @@ public class ParticipantDto
// Method to map from Participant entity
public static ParticipantDto FromEntity(Participant participant)
{
return new ParticipantDto
return (participant == null)?null: new ParticipantDto
{
Id = participant.ParticipantId,
Name = participant.Name,
};
}
}


public class DocumentReferralDto
{
// Properties for the DTO using business IDs
public DocumentReferralId DocumentReferralId { get; set; }
public DocumentId DocumentId { get; set; }
public ParticipantId ReferrerUserId { get; set; }
public string ReferrerUserFullName { get; set; } // Full name of the referrer (can be mapped from Participant)
public ParticipantId ReceiverUserId { get; set; }
public string ReceiverUserFullName { get; set; } // Full name of the receiver (can be mapped from Participant)
public ReferralStatus Status { get; set; }
public DateTime ReferralDate { get; set; }
public DateTime? ViewedDate { get; set; }
public DateTime? RespondedDate { get; set; }
public string ResponseContent { get; set; }
public DocumentReferralId? ParentReferralId { get; set; }

// Constructor to map the entity to the DTO
public DocumentReferralDto(DocumentReferralEntity entity)
{
DocumentReferralId = entity.DocumentReferralId;
DocumentId = entity.DocumentId;
ReferrerUserId = entity.ReferrerUserId;
ReceiverUserId = entity.ReceiverUserId;
Status = entity.Status;
ReferralDate = entity.ReferralDate;
ViewedDate = entity.ViewedDate;
RespondedDate = entity.RespondedDate;
ResponseContent = entity.ResponseContent;
ParentReferralId = entity.ParentReferralId;

// Optionally, populate the full names for users if you have access to them
// (You can either fetch them separately or include them in the entity via navigation properties)
ReferrerUserFullName = entity.ReferrerUser?.Name ?? string.Empty;
ReceiverUserFullName = entity.ReceiverUser?.Name ?? string.Empty;
}

// Static method to create the DTO from a DocumentReferralEntity
public static DocumentReferralDto FromEntity(DocumentReferralEntity entity)
{
return new DocumentReferralDto(entity);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,33 +45,55 @@ public override async Task HandleAsync(CreateDocumentRequest req, CancellationTo
ThrowError("Participant not found for the current user.");
}

// Find the participant ID associated with the user ID
// Find the participant ID associated with the receiver ID
var participantReceiverId = await _dbContext.Participants
.Where(p => p.ParticipantId == ParticipantId.NewId(req.ReceiverParticipantId))
.Select(p => p.ParticipantId)
.FirstOrDefaultAsync(ct);

if (participantReceiverId == null)
{
ThrowError("Participant not found for the current user.");
ThrowError("Receiver participant not found.");
}

var document = new DocumentAggregateRoot(req.Title, req.Content, participantId, participantReceiverId,
DocumentType.Internal);
// Generate a unique document number for the current year
var currentYear = DateTime.UtcNow.Year;
var documentNumber = await GenerateDocumentNumberAsync(currentYear, ct);

// Create the document with the generated number
var document = new DocumentAggregateRoot(
req.Title,
req.Content,
participantId,
participantReceiverId,
DocumentType.Internal,
documentNumber
);

// Save the document
await _dbContext.Documents.AddAsync(document, ct);
await _dbContext.SaveChangesAsync(ct);

// Return paginated response
await SendOkAsync( ct);
// Return response
await SendOkAsync(DocumentDto.FromEntity(document), ct);
}

private async Task<int> GenerateDocumentNumberAsync(int year, CancellationToken ct)
{
// Count documents created in the current year
var count = await _dbContext.Documents
.Where(d => d.LetterDate.Year == year)
.CountAsync(ct);

// Increment by 1 to generate the new document number
return count + 1;
}

private UserId? GetCurrentUserId()
{
// Retrieve user ID from claims
var userIdClaim =
User.Claims.FirstOrDefault(c =>
c.Type == ClaimTypes.NameIdentifier); // Adjust claim type as per your system
var userIdClaim = User.Claims.FirstOrDefault(c =>
c.Type == ClaimTypes.NameIdentifier); // Adjust claim type as per your system
return userIdClaim != null ? UserId.NewId(Guid.Parse(userIdClaim.Value)) : null;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
using System.Security.Claims;
using FastEndpoints;
using Microsoft.EntityFrameworkCore;
using Nezam.EEs.Shared.Domain.Identity.User;
using Nezam.EES.Slice.Secretariat.Application.Dto;
using Nezam.EES.Slice.Secretariat.Domains.Documents.ValueObjects;
using Nezam.EES.Slice.Secretariat.Infrastructure.EntityFrameworkCore;

namespace Nezam.EES.Slice.Secretariat.Application.UseCases.Documents.GetDocumentAttachments
{
public class GetDocumentAttachmentsRequest
{
public Guid DocumentId { get; set; }
}

public class GetDocumentAttachmentsResponse
{
public List<DocumentAttachmentDto> Attachments { get; set; }
}



public class GetDocumentAttachmentsEndpoint : Endpoint<GetDocumentAttachmentsRequest, GetDocumentAttachmentsResponse>
{
private readonly ISecretariatDbContext _dbContext;

public GetDocumentAttachmentsEndpoint(ISecretariatDbContext dbContext)
{
_dbContext = dbContext;
}

public override void Configure()
{
Get("/api/documents/{documentId}/attachments");
// Note: The {documentId} part should map to the DocumentId parameter.
}

public override async Task HandleAsync(GetDocumentAttachmentsRequest req, CancellationToken ct)
{
// Extract current user ID from claims
var userId = GetCurrentUserId();

if (userId == null)
{
ThrowError("User ID not found in claims.");
}

var documentId = DocumentId.NewId(req.DocumentId);

// Query the document to ensure the user has access
var document = await _dbContext.Documents
.AsNoTracking()
.Include(d => d.Attachments)
.Where(d => d.DocumentId == documentId)
.FirstOrDefaultAsync(ct);

if (document == null)
{
ThrowError("Document not found.");
}

// Ensure user is authorized to access this document (customize this check)
var participantId = await _dbContext.Participants
.Where(p => p.UserId == userId)
.Select(p => p.ParticipantId)
.FirstOrDefaultAsync(ct);

if (participantId == null ||
(document.OwnerParticipantId != participantId && document.ReceiverParticipantId != participantId))
{
ThrowError("Unauthorized access to the document.");
}

// Map to the response DTO
var attachments = document.Attachments.Select(DocumentAttachmentDto.FromEntity).ToList();

// Send the response with document attachments
await SendOkAsync(new GetDocumentAttachmentsResponse { Attachments = attachments }, ct);
}

private UserId? GetCurrentUserId()
{
// Retrieve user ID from claims
var userIdClaim =
User.Claims.FirstOrDefault(c =>
c.Type == ClaimTypes.NameIdentifier); // Adjust claim type as per your system
return userIdClaim != null ? UserId.NewId(Guid.Parse(userIdClaim.Value)) : null;
}
}
}
Loading

0 comments on commit 6ecd150

Please sign in to comment.