Skip to content

Commit

Permalink
Merge pull request #25 from snax4a/feature/offers-api
Browse files Browse the repository at this point in the history
Add offers api and inquiry email sender job
  • Loading branch information
snax4a authored Feb 26, 2022
2 parents bf374a0 + b804639 commit 4141ae3
Show file tree
Hide file tree
Showing 74 changed files with 6,486 additions and 158 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System.Net;

namespace FSH.WebApi.Application.Identity;
namespace FSH.WebApi.Application.Common.Exceptions;

public class InternalServerException : CustomException
{
Expand Down
2 changes: 1 addition & 1 deletion src/Core/Application/Common/Mailing/IMailService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ namespace FSH.WebApi.Application.Common.Mailing;

public interface IMailService : ITransientService
{
Task SendAsync(MailRequest request);
Task SendAsync(MailRequest request, CancellationToken ct);
}
2 changes: 2 additions & 0 deletions src/Core/Application/Exchange/Groups/CreateGroupRequest.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using FSH.WebApi.Application.Exchange.Groups.Specifications;

namespace FSH.WebApi.Application.Exchange.Groups;

public class CreateGroupRequest : IRequest<Guid>
Expand Down
9 changes: 7 additions & 2 deletions src/Core/Application/Exchange/Groups/DeleteGroupRequest.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using FSH.WebApi.Application.Exchange.Traders;
using FSH.WebApi.Application.Exchange.Traders.Specifications;

namespace FSH.WebApi.Application.Exchange.Groups;

Expand All @@ -16,8 +16,13 @@ public class DeleteGroupRequestHandler : IRequestHandler<DeleteGroupRequest, Gui
private readonly IReadRepository<Trader> _traderRepo;
private readonly IStringLocalizer<DeleteGroupRequestHandler> _localizer;

public DeleteGroupRequestHandler(IRepositoryWithEvents<Group> groupRepo, IReadRepository<Trader> traderRepo, IStringLocalizer<DeleteGroupRequestHandler> localizer) =>
public DeleteGroupRequestHandler(
IRepositoryWithEvents<Group> groupRepo,
IReadRepository<Trader> traderRepo,
IStringLocalizer<DeleteGroupRequestHandler> localizer)
{
(_groupRepo, _traderRepo, _localizer) = (groupRepo, traderRepo, localizer);
}

public async Task<Guid> Handle(DeleteGroupRequest request, CancellationToken cancellationToken)
{
Expand Down
18 changes: 10 additions & 8 deletions src/Core/Application/Exchange/Groups/GetGroupRequest.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace FSH.WebApi.Application.Exchange.Groups;
using FSH.WebApi.Application.Exchange.Groups.Specifications;

namespace FSH.WebApi.Application.Exchange.Groups;

public class GetGroupRequest : IRequest<GroupDto>
{
Expand All @@ -7,19 +9,19 @@ public class GetGroupRequest : IRequest<GroupDto>
public GetGroupRequest(Guid id) => Id = id;
}

public class GroupByIdSpec : Specification<Group, GroupDto>, ISingleResultSpecification
{
public GroupByIdSpec(Guid id, Guid userId) =>
Query.Where(g => g.Id == id && g.CreatedBy == userId);
}

public class GetGroupRequestHandler : IRequestHandler<GetGroupRequest, GroupDto>
{
private readonly ICurrentUser _currentUser;
private readonly IRepository<Group> _repository;
private readonly IStringLocalizer<GetGroupRequestHandler> _localizer;

public GetGroupRequestHandler(ICurrentUser currentUser, IRepository<Group> repository, IStringLocalizer<GetGroupRequestHandler> localizer) => (_currentUser, _repository, _localizer) = (currentUser, repository, localizer);
public GetGroupRequestHandler(
ICurrentUser currentUser,
IRepository<Group> repository,
IStringLocalizer<GetGroupRequestHandler> localizer)
{
(_currentUser, _repository, _localizer) = (currentUser, repository, localizer);
}

public async Task<GroupDto> Handle(GetGroupRequest request, CancellationToken cancellationToken)
{
Expand Down
14 changes: 5 additions & 9 deletions src/Core/Application/Exchange/Groups/SearchGroupsRequest.cs
Original file line number Diff line number Diff line change
@@ -1,24 +1,20 @@
using FSH.WebApi.Application.Exchange.Groups.Specifications;

namespace FSH.WebApi.Application.Exchange.Groups;

public class SearchGroupsRequest : PaginationFilter, IRequest<PaginationResponse<GroupDto>>
{
}

public class SearchGroupsSpec : EntitiesByPaginationFilterSpec<Group, GroupDto>
{
public SearchGroupsSpec(SearchGroupsRequest request, Guid userId)
: base(request) => Query
.Where(g => g.CreatedBy == userId)
.OrderBy(g => g.Name, !request.HasOrderBy());
}

public class SearchGroupsRequestHandler : IRequestHandler<SearchGroupsRequest, PaginationResponse<GroupDto>>
{
private readonly ICurrentUser _currentUser;
private readonly IReadRepository<Group> _repository;

public SearchGroupsRequestHandler(ICurrentUser currentUser, IReadRepository<Group> repository) =>
public SearchGroupsRequestHandler(ICurrentUser currentUser, IReadRepository<Group> repository)
{
(_currentUser, _repository) = (currentUser, repository);
}

public async Task<PaginationResponse<GroupDto>> Handle(SearchGroupsRequest request, CancellationToken cancellationToken)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace FSH.WebApi.Application.Exchange.Groups.Specifications;

public class GroupByIdSpec : Specification<Group, GroupDto>, ISingleResultSpecification
{
public GroupByIdSpec(Guid id, Guid userId) =>
Query.Where(g => g.Id == id && g.CreatedBy == userId);
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace FSH.WebApi.Application.Exchange.Groups;
namespace FSH.WebApi.Application.Exchange.Groups.Specifications;

public class GroupByNameAndOwnerSpec : Specification<Group>, ISingleResultSpecification
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace FSH.WebApi.Application.Exchange.Groups.Specifications;

public class SearchGroupsSpec : EntitiesByPaginationFilterSpec<Group, GroupDto>
{
public SearchGroupsSpec(SearchGroupsRequest request, Guid userId)
: base(request) => Query
.Where(g => g.CreatedBy == userId)
.OrderBy(g => g.Name, !request.HasOrderBy());
}
2 changes: 2 additions & 0 deletions src/Core/Application/Exchange/Groups/UpdateGroupRequest.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using FSH.WebApi.Application.Exchange.Groups.Specifications;

namespace FSH.WebApi.Application.Exchange.Groups;

public class UpdateGroupRequest : IRequest<Guid>
Expand Down
24 changes: 14 additions & 10 deletions src/Core/Application/Exchange/Inquiries/CreateInquiryRequest.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
using FSH.WebApi.Application.Exchange.Inquiries.Specifications;
using MassTransit;

namespace FSH.WebApi.Application.Exchange.Inquiries;

public class UserInquiriesSpec : Specification<Inquiry>, ISingleResultSpecification
{
public UserInquiriesSpec(Guid userId) => Query.Where(i => i.CreatedBy == userId);
}

public class CreateInquiryRequest : IRequest<Guid>
{
public string Name { get; set; } = default!;
Expand Down Expand Up @@ -50,11 +46,14 @@ public class CreateInquiryRequestHandler : IRequestHandler<CreateInquiryRequest,

// Add Domain Events automatically by using IRepositoryWithEvents
private readonly IRepositoryWithEvents<Inquiry> _repository;
private readonly IJobService _jobService;

public CreateInquiryRequestHandler(ICurrentUser currentUser, IRepositoryWithEvents<Inquiry> repository) =>
(_currentUser, _repository) = (currentUser, repository);
public CreateInquiryRequestHandler(ICurrentUser currentUser, IRepositoryWithEvents<Inquiry> repository, IJobService jobService)
{
(_currentUser, _repository, _jobService) = (currentUser, repository, jobService);
}

public async Task<Guid> Handle(CreateInquiryRequest request, CancellationToken cancellationToken)
public async Task<Guid> Handle(CreateInquiryRequest request, CancellationToken ct)
{
Guid inquiryId = NewId.Next().ToGuid();
List<InquiryProduct> products = new();
Expand All @@ -65,10 +64,15 @@ public async Task<Guid> Handle(CreateInquiryRequest request, CancellationToken c
}

var spec = new UserInquiriesSpec(_currentUser.GetUserId());
int referenceNumber = await _repository.CountAsync(spec, cancellationToken);
int referenceNumber = await _repository.CountAsync(spec, ct);
var inquiry = new Inquiry(inquiryId, referenceNumber + 1, request.Name, request.Title, products, request.RecipientIds);

await _repository.AddAsync(inquiry, cancellationToken);
await _repository.AddAsync(inquiry, ct);

foreach (Guid traderId in request.RecipientIds)
{
_jobService.Enqueue<IInquirySenderJob>(x => x.SendAsync(inquiry.Id, traderId, CancellationToken.None));
}

return inquiry.Id;
}
Expand Down
21 changes: 10 additions & 11 deletions src/Core/Application/Exchange/Inquiries/GetInquiryRequest.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace FSH.WebApi.Application.Exchange.Inquiries;
using FSH.WebApi.Application.Exchange.Inquiries.Specifications;

namespace FSH.WebApi.Application.Exchange.Inquiries;

public class GetInquiryRequest : IRequest<InquiryDetailsDto>
{
Expand All @@ -7,22 +9,19 @@ public class GetInquiryRequest : IRequest<InquiryDetailsDto>
public GetInquiryRequest(Guid id) => Id = id;
}

public class InquiryDetailsSpec : Specification<Inquiry, InquiryDetailsDto>, ISingleResultSpecification
{
public InquiryDetailsSpec(Guid id, Guid userId) =>
Query
.Where(i => i.Id == id && i.CreatedBy == userId)
.Include(i => i.Products)
.Include(i => i.InquiryRecipients);
}

public class GetInquiryRequestHandler : IRequestHandler<GetInquiryRequest, InquiryDetailsDto>
{
private readonly ICurrentUser _currentUser;
private readonly IRepository<Inquiry> _repository;
private readonly IStringLocalizer<GetInquiryRequestHandler> _localizer;

public GetInquiryRequestHandler(ICurrentUser currentUser, IRepository<Inquiry> repository, IStringLocalizer<GetInquiryRequestHandler> localizer) => (_currentUser, _repository, _localizer) = (currentUser, repository, localizer);
public GetInquiryRequestHandler(
ICurrentUser currentUser,
IRepository<Inquiry> repository,
IStringLocalizer<GetInquiryRequestHandler> localizer)
{
(_currentUser, _repository, _localizer) = (currentUser, repository, localizer);
}

public async Task<InquiryDetailsDto> Handle(GetInquiryRequest request, CancellationToken cancellationToken)
{
Expand Down
9 changes: 9 additions & 0 deletions src/Core/Application/Exchange/Inquiries/IInquirySenderJob.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System.ComponentModel;

namespace FSH.WebApi.Application.Exchange.Inquiries;

public interface IInquirySenderJob : IScopedService
{
[DisplayName("Send inquiry emails to all recipients of the inquiry.")]
Task SendAsync(Guid inquiryId, Guid traderId, CancellationToken cancellationToken);
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,20 @@
using FSH.WebApi.Application.Exchange.Inquiries.Specifications;

namespace FSH.WebApi.Application.Exchange.Inquiries;

public class SearchInquiriesRequest : PaginationFilter, IRequest<PaginationResponse<InquiryDto>>
{
}

public class SearchInquiriesSpec : EntitiesByPaginationFilterSpec<Inquiry, InquiryDto>
{
public SearchInquiriesSpec(SearchInquiriesRequest request, Guid userId)
: base(request) => Query
.Where(i => i.CreatedBy == userId)
.OrderByDescending(i => i.ReferenceNumber, !request.HasOrderBy());
}

public class SearchInquiriesRequestHandler : IRequestHandler<SearchInquiriesRequest, PaginationResponse<InquiryDto>>
{
private readonly ICurrentUser _currentUser;
private readonly IReadRepository<Inquiry> _repository;

public SearchInquiriesRequestHandler(ICurrentUser currentUser, IReadRepository<Inquiry> repository) =>
public SearchInquiriesRequestHandler(ICurrentUser currentUser, IReadRepository<Inquiry> repository)
{
(_currentUser, _repository) = (currentUser, repository);
}

public async Task<PaginationResponse<InquiryDto>> Handle(SearchInquiriesRequest request, CancellationToken cancellationToken)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace FSH.WebApi.Application.Exchange.Inquiries.Specifications;

public class InquiryByIdAndTraderSpec : Specification<Inquiry, InquiryDetailsDto>, ISingleResultSpecification
{
public InquiryByIdAndTraderSpec(Guid inquiryId, Guid traderId) =>
Query
.Include(i => i.InquiryRecipients)
.Where(i => i.Id == inquiryId && i.InquiryRecipients.Any(ir => ir.TraderId == traderId));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace FSH.WebApi.Application.Exchange.Inquiries.Specifications;

public class InquiryDetailsSpec : Specification<Inquiry, InquiryDetailsDto>, ISingleResultSpecification
{
public InquiryDetailsSpec(Guid id, Guid userId) =>
Query
.Where(i => i.Id == id && i.CreatedBy == userId)
.Include(i => i.Products)
.Include(i => i.InquiryRecipients);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace FSH.WebApi.Application.Exchange.Inquiries.Specifications;

public class SearchInquiriesSpec : EntitiesByPaginationFilterSpec<Inquiry, InquiryDto>
{
public SearchInquiriesSpec(SearchInquiriesRequest request, Guid userId)
: base(request) => Query
.Where(i => i.CreatedBy == userId)
.OrderByDescending(i => i.ReferenceNumber, !request.HasOrderBy());
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace FSH.WebApi.Application.Exchange.Inquiries.Specifications;

public class UserInquiriesSpec : Specification<Inquiry>, ISingleResultSpecification
{
public UserInquiriesSpec(Guid userId) => Query.Where(i => i.CreatedBy == userId);
}
Loading

0 comments on commit 4141ae3

Please sign in to comment.