Commit 142bdb84 authored by hasan khaddour's avatar hasan khaddour

Add Domain Models (Entities and Aggregate )

parent 804e6ccf
using MediatR;
using FluentResults;
using FluentValidation;
using MediatR;
using PSManagement.Application.Common.Exceptions;
using PSManagement.SharedKernel.CQRS.Command;
using System;
using System.Collections.Generic;
using System.Linq;
......@@ -10,45 +13,41 @@ using ValidationException = PSManagement.Application.Common.Exceptions.Validatio
namespace PSManagement.Application.Behaviors.ValidationBehavior
{
public sealed class ValidationBehavior<TRequest, TResponse> //: IPipelineBehavior<TRequest, TResponse>
// where TRequest : class, ICommand<TResponse>
{
//private readonly IEnumerable<IValidator<TRequest>> _validators;
//public ValidationBehavior(IEnumerable<IValidator<TRequest>> validators) => _validators = validators;
public class ValidationBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
where TRequest : IRequest<TResponse> where TResponse : ResultBase
{
private readonly IEnumerable<IValidator<TRequest>> _validators;
//public async Task<TResponse> Handle(
// TRequest request,
// CancellationToken cancellationToken,
// RequestHandlerDelegate<TResponse> next)
//{
// if (!_validators.Any())
// {
// return await next();
// }
public ValidationBehavior(IEnumerable<IValidator<TRequest>> validators = null)
{
_validators = validators;
}
// var context = new ValidationContext<TRequest>(request);
public async Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate<TResponse> next)
{
var context = new ValidationContext<TRequest>(request);
if (_validators is null) {
// var errorsDictionary = _validators
// .Select(x => x.Validate(context))
// .SelectMany(x => x.Errors)
// .Where(x => x != null)
// .GroupBy(
// x => x.PropertyName,
// x => x.ErrorMessage,
// (propertyName, errorMessages) => new
// {
// Key = propertyName,
// Values = errorMessages.Distinct().ToArray()
// })
// .ToDictionary(x => x.Key, x => x.Values);
return await next();
}
var failures = _validators
.Select(v => v.Validate(context))
.SelectMany(result => result.Errors)
.Where(f => f != null)
.ToList();
// if (errorsDictionary.Any())
// {
// throw new ValidationException(errorsDictionary);
// }
if (failures.Count != 0)
{
var result =Result.Fail("validation Error.");
foreach (var failure in failures)
{
result.Reasons.Add(new Error(failure.ErrorMessage));
}
return (dynamic)result;
}
// return await next();
//}
return await next();
}
}
}
//using PSManagement.SharedKernel.Utilities;

using FluentResults;
using System;
using System.Threading.Tasks;
......
......@@ -6,7 +6,7 @@ namespace PSManagement.Application.Customers.Common
public class ContactInfoDTO
{
public String ConatctValue { get; set; }
public String ContactTpe { get; set; }
public String ContactType { get; set; }
}
}
\ No newline at end of file
......@@ -27,7 +27,7 @@ namespace PSManagement.Application.Customers.UseCases.Commands.AddContactInfo
return Result.Fail(CustomerErrors.InvalidEntryError);
}
ContactInfo contact = new ContactInfo(request.ContactValue,request.ContactType);
ContactInfo contact = new (request.ContactValue,request.ContactType);
customer.AddContactInfo(contact);
await _customersRepository.UpdateAsync(customer);
return Result.Ok();
......
using FluentResults;

using FluentResults;
using PSManagement.Application.Customers.Common;
using PSManagement.Domain.Customers.Aggregate;
using PSManagement.Domain.Customers.ValueObjects;
......
using System;
using FluentValidation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
......@@ -6,7 +7,12 @@ using System.Threading.Tasks;
namespace PSManagement.Application.Customers.UseCases.Commands.CreateCustomer
{
class CreateCustomerCommandValidator
public class CreateCustomerCommandValidator : AbstractValidator<CreateCustomerCommand>
{
public CreateCustomerCommandValidator()
{
RuleFor(x => x.CustomerName).NotEmpty();
RuleFor(x => x.Email).EmailAddress();
}
}
}
using FluentResults;
using PSManagement.Application.Customers.Common;
using PSManagement.SharedKernel.CQRS.Query;
using System;
using System.Linq;
using System.Text;
namespace PSManagement.Application.Customers.UseCases.Queries.GetCustomer
{
public record GetCustomerQuery(int customerId) : IQuery<Result<CustomerDTO>>;
}
using AutoMapper;
using FluentResults;
using PSManagement.Application.Customers.Common;
using PSManagement.Domain.Customers.Aggregate;
using PSManagement.Domain.Customers.DomainErrors;
using PSManagement.Domain.Customers.Repositories;
using PSManagement.SharedKernel.CQRS.Query;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace PSManagement.Application.Customers.UseCases.Queries.GetCustomer
{
public class GetCustomerQueryHandler : IQueryHandler<GetCustomerQuery, Result<CustomerDTO>>
{
private readonly ICustomersRepository _customersRepository;
private readonly IMapper _mapper;
public GetCustomerQueryHandler(ICustomersRepository customersRepository, IMapper mapper)
{
_customersRepository = customersRepository;
_mapper = mapper;
}
public async Task<Result<CustomerDTO>> Handle(GetCustomerQuery request, CancellationToken cancellationToken)
{
Customer customer = await _customersRepository.GetByIdAsync(request.customerId);
if (customer is null) {
return Result.Fail(CustomerErrors.InvalidEntryError);
}
return Result.Ok(_mapper.Map<CustomerDTO>(customer));
}
}
}
using FluentResults;
using PSManagement.Application.Customers.Common;
using PSManagement.SharedKernel.CQRS.Query;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PSManagement.Application.Customers.UseCases.Queries.ListAllCustomers
{
public record ListAllCustomersQuery() : IQuery<Result<IEnumerable<CustomerDTO>>>;
}
using AutoMapper;
using FluentResults;
using PSManagement.Application.Customers.Common;
using PSManagement.Domain.Customers.Repositories;
using PSManagement.SharedKernel.CQRS.Query;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace PSManagement.Application.Customers.UseCases.Queries.ListAllCustomers
{
public class ListAllCustomersQueryHandler : IQueryHandler<ListAllCustomersQuery, Result<IEnumerable<CustomerDTO>>>
{
private readonly ICustomersRepository _customersRepository;
private readonly IMapper _mapper;
public ListAllCustomersQueryHandler(ICustomersRepository customersRepository, IMapper mapper)
{
_customersRepository = customersRepository;
_mapper = mapper;
}
public async Task<Result<IEnumerable<CustomerDTO>>> Handle(ListAllCustomersQuery request, CancellationToken cancellationToken)
{
return Result.Ok( _mapper.Map<IEnumerable<CustomerDTO>>(await _customersRepository.ListAsync()));
}
}
}
......@@ -5,6 +5,8 @@ using MediatR;
using System.Reflection;
using AutoMapper;
using PSManagement.Application.Mappers;
using FluentValidation;
using PSManagement.Application.Behaviors.ValidationBehavior;
namespace PSManagement.Application.DI
{
......@@ -13,7 +15,16 @@ namespace PSManagement.Application.DI
public static IServiceCollection AddApplication(this IServiceCollection services)
{
//services.AddMediatR();
services.AddMediatR(Assembly.GetExecutingAssembly());
services.AddMediatR(typeof(DependencyInjection).Assembly);
// Register the pipeline behaviors explicitly
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(ValidationBehavior<,>));
// Register FluentValidation validators
services.AddValidatorsFromAssembly(Assembly.GetExecutingAssembly());
services.AddAutoMapper(typeof(CustomerMapperConfiguration));
......
......@@ -5,17 +5,16 @@
</PropertyGroup>
<ItemGroup>
<Folder Include="Abstraction\" />
<Folder Include="Behaviors\AuthorizationBehavior\" />
<Folder Include="Customers\UseCases\Queries\ListAllCustomers\" />
<Folder Include="Customers\UseCases\Queries\GetCustomer\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="7.0.1" />
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="5.0.1" />
<PackageReference Include="MediatR" Version="5.1.0" />
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="5.1.0" />
<PackageReference Include="FluentValidation" Version="8.6.3" />
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="8.6.3" />
<PackageReference Include="MediatR" Version="8.0.1" />
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.2" />
</ItemGroup>
......
......@@ -14,7 +14,7 @@ namespace PSManagement.Domain.Customers.Aggregate
public String CustomerName { get; set; }
public Address Address { get; set; }
public String Email { get; set; }
public IEnumerable<ContactInfo> ContactInfo { get; private set; }
public ICollection<ContactInfo> ContactInfo { get; private set; }
public Customer()
{
......@@ -34,8 +34,7 @@ namespace PSManagement.Domain.Customers.Aggregate
{
ContactInfo = new List<ContactInfo>();
}
ContactInfo= ContactInfo.Append(contactInfo);
ContactInfo.Add(contactInfo);
}
......
using FluentResults;
using PSManagement.SharedKernel.DomainErrors;
using System;
using System.Collections.Generic;
using System.Linq;
......@@ -9,6 +9,6 @@ namespace PSManagement.Domain.Customers.DomainErrors
{
public static class CustomerErrors
{
public static Error InvalidEntryError { get; } = new Error("Customer Invalid Entry Erorr.");
public static DomainError InvalidEntryError { get; } = new DomainError("Invalid Customer Entry.",new DomainError("Invalid Customer Data"));
}
}
......@@ -13,17 +13,17 @@ namespace PSManagement.Domain.Customers.Entities
public sealed class ContactInfo : BaseEntity
{
public String ContactType { get; private set; }
public String ConatctValue { get; private set; }
public String ContactValue { get; private set; }
public ContactInfo(string conatctValue, string contactType)
public ContactInfo(string contactValue, string contactType)
{
ConatctValue = conatctValue;
ContactValue = contactValue;
ContactType = contactType;
}
public ContactInfo()
{
}
}
......
using PSManagement.Domain.Employees.Aggregate;
using PSManagement.SharedKernel.Aggregate;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PSManagement.Domain.Departments.Aggregate
{
public class Department :IAggregateRoot
{
public String Name { get; set; }
public Department(string name)
{
Name = name;
}
public Department()
{
}
}
}
using PSManagement.SharedKernel.Aggregate;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PSManagement.Domain.Employees.Aggregate
{
public class Employee :IAggregateRoot
{
public int HIASTId{ get; set; }
public PersonalInfo PersonalInfo { get; set; }
public Availability Availability { get; set; }
public Employee()
{
}
public Employee(Availability availability, PersonalInfo personalInfo, int hiastId)
{
Availability = availability;
PersonalInfo = personalInfo;
HIASTId = hiastId;
}
}
public record PersonalInfo(
String FirstName ,
String LastName
);
public record Availability (
int WorkingHours ,
Boolean IsAvailable
);
}
using FluentResults;
using PSManagement.SharedKernel.DomainErrors;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PSManagement.Domain.Identity.DomainErrors
{
public class InvalidLoginDataError : IDomainError
{
public List<IError> Reasons => new(new[] { new Error("The User Email Or Password Wrong.") });
public string Message => "Invalid Login Attempt.";
public Dictionary<string, object> Metadata => new();
}
}
using FluentResults;
using PSManagement.SharedKernel.DomainErrors;
using PSManagement.SharedKernel.DomainErrors;
using System;
using System.Collections.Generic;
using System.Linq;
......@@ -8,12 +7,10 @@ using System.Threading.Tasks;
namespace PSManagement.Domain.Identity.DomainErrors
{
public class AlreadyExistError : IDomainError
public class UserErrors
{
public List<IError> Reasons => new(new[] { new Error("The User Email Already Exist.") });
public static readonly DomainError AlreadyUserExist = new ("The User Email Already Exist.", new DomainError("User email is already exist"));
public static readonly DomainError InvalidLoginAttempt = new ("The User Email or Password Are Incorrect.",new DomainError( "invalid credentails for login"));
public string Message => "The Email Is Already Exist.";
public Dictionary<string, object> Metadata => new();
}
}
......@@ -7,14 +7,8 @@
<ItemGroup>
<Folder Include="Identity\Entities\" />
<Folder Include="Identity\ValueObjects\" />
<Folder Include="Employees\" />
<Folder Include="Departments\" />
<Folder Include="Phases\" />
<Folder Include="ProjectTypes\" />
<Folder Include="Tracking\" />
<Folder Include="Projects\DomainErrors\" />
<Folder Include="Projects\Entities\" />
<Folder Include="Projects\ValueObjects\" />
</ItemGroup>
<ItemGroup>
......
using PSManagement.SharedKernel.Aggregate;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PSManagement.Domain.ProjectTypes.Aggregate
{
public class ProjectType : IAggregateRoot
{
public String TypeName { get; set; }
public String Description { get; set; }
public int WorkerCount { get; set; }
}
}
using System;
using PSManagement.Domain.Departments.Aggregate;
using PSManagement.Domain.Employees.Aggregate;
using PSManagement.Domain.Steps.Aggregate;
using PSManagement.SharedKernel.Aggregate;
using System.Collections.Generic;
using System.Linq;
using System.Text;
......@@ -6,7 +9,21 @@ using System.Threading.Tasks;
namespace PSManagement.Domain.Projects.Aggregate
{
class Project
public class Project : IAggregateRoot
{
public ProposalInfo ProposalInfo { get; set; }
public ProjectInfo ProjectInfo { get; set; }
public Aggreement ProjectAggreement { get; set; }
public ICollection<Employee> Participants { get; set; }
public ICollection<Step> Steps { get; set; }
public Employee TeamLeader { get; set; }
public Department Executer { get; set; }
public Employee Proposer { get; set; }
public Project()
{
}
}
}
using System;
namespace PSManagement.Domain.Projects.Aggregate
{
public record Aggreement (
int AggreementNumber ,
DateTime AggreementDate
);
}
using System;
namespace PSManagement.Domain.Projects.Aggregate
{
public record ProjectInfo(
String Name ,
String Code ,
String Description
);
}
using PSManagement.Domain.Customers.Aggregate;
using System;
namespace PSManagement.Domain.Projects.Aggregate
{
public record ProposalInfo (
int ProposingBookNumber ,
DateTime ProposingBookDate
);
}
using PSManagement.Domain.Steps.Entities;
using PSManagement.SharedKernel.Aggregate;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PSManagement.Domain.Steps.Aggregate
{
public class Step :IAggregateRoot
{
public String StepName { get; set; }
public String Description { get; set; }
public int Duration { get; set; }
public DateTime StartDate { get; set; }
public ICollection<Item> Purchases { get; set; }
public Step()
{
}
}
}
using PSManagement.SharedKernel.Entities;
using PSManagement.SharedKernel.ValueObjects;
using System;
namespace PSManagement.Domain.Steps.Entities
{
public class Item : BaseEntity
{
public string ItemName { get; set; }
public string ItemDescription { get; set; }
public Money Price { get; set; }
public Item()
{
}
}
}
using PSManagement.Domain.Projects.Aggregate;
using PSManagement.Domain.Tracking.Entities;
using PSManagement.SharedKernel.Aggregate;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PSManagement.Domain.Tracking
{
public class Track : IAggregateRoot
{
public DateTime TrackDate { get; set; }
public String TrackNote { get; set; }
public Project Project { get; set; }
public ICollection<StepTrack> StepsTracks { get; set; }
public Track()
{
}
}
}
using PSManagement.Domain.Employees.Aggregate;
using PSManagement.SharedKernel.Entities;
namespace PSManagement.Domain.Tracking.Entities
{
public class EmployeeTrack : BaseEntity
{
public Employee Employee { get; set; }
public int WorkingHour { get; set; }
public EmployeeTrack()
{
}
}
}
using PSManagement.Domain.Steps.Aggregate;
using PSManagement.SharedKernel.Entities;
using System.Collections.Generic;
namespace PSManagement.Domain.Tracking.Entities
{
public class StepTrack : BaseEntity
{
public Step Step { get; set; }
public IEnumerable<EmployeeTrack> EmployeeTracks { get; set; }
public StepTrack()
{
}
}
}
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