diff --git a/.version b/.version
index a6e4449..d37fa68 100644
--- a/.version
+++ b/.version
@@ -1 +1 @@
-0.8.15.22
\ No newline at end of file
+0.9.16.23
\ No newline at end of file
diff --git a/NetinaShop.Api/NetinaShop.Api.csproj b/NetinaShop.Api/NetinaShop.Api.csproj
index bb3e78d..52453f0 100644
--- a/NetinaShop.Api/NetinaShop.Api.csproj
+++ b/NetinaShop.Api/NetinaShop.Api.csproj
@@ -6,8 +6,8 @@
enable
true
Linux
- 0.8.15.22
- 0.8.15.22
+ 0.9.16.23
+ 0.9.16.23
diff --git a/NetinaShop.Api/Program.cs b/NetinaShop.Api/Program.cs
index 8ac91dc..4add805 100644
--- a/NetinaShop.Api/Program.cs
+++ b/NetinaShop.Api/Program.cs
@@ -1,3 +1,5 @@
+using NetinaShop.Repository.Behaviors;
+
var builder = WebApplication.CreateBuilder(args);
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
builder.Host.UseSerilog();
@@ -71,16 +73,19 @@ builder.Host.ConfigureContainer(builder =>
builder.RegisterMediatR(MediatRConfigurationBuilder
.Create(typeof(RepositoryConfig).Assembly)
+ .WithCustomPipelineBehavior(typeof(ValidationBehavior<,>))
.WithAllOpenGenericHandlerTypesRegistered()
.Build());
builder.RegisterMediatR(MediatRConfigurationBuilder
.Create(typeof(CoreConfig).Assembly)
+ .WithCustomPipelineBehavior(typeof(ValidationBehavior<,>))
.WithAllOpenGenericHandlerTypesRegistered()
.Build());
builder.RegisterMediatR(MediatRConfigurationBuilder
.Create(typeof(DomainConfig).Assembly)
+ .WithCustomPipelineBehavior(typeof(ValidationBehavior<,>))
.WithAllOpenGenericHandlerTypesRegistered()
.Build());
});
diff --git a/NetinaShop.Common/Models/Exception/ValidationException.cs b/NetinaShop.Common/Models/Exception/ValidationException.cs
new file mode 100644
index 0000000..5c513ef
--- /dev/null
+++ b/NetinaShop.Common/Models/Exception/ValidationException.cs
@@ -0,0 +1,20 @@
+namespace NetinaShop.Common.Models.Exception;
+
+public class ValidationException : System.Exception
+{
+ public ValidationException() : base("Validation has been failed")
+ {
+
+ }
+
+ public ValidationException(params ValidationError[] validationErrors) : base($"{string.Join(",", validationErrors.Select(v => v.ErrorMessage))}")
+ {
+
+ }
+
+ public ValidationException(List validationErrors) : base($"{string.Join(",", validationErrors.Select(v => v.ErrorMessage))}")
+ {
+
+ }
+}
+public sealed record ValidationError(string PropertyName, string ErrorMessage);
\ No newline at end of file
diff --git a/NetinaShop.Domain/Dtos/FilterDtos/BaseFilterDto.cs b/NetinaShop.Domain/Dtos/FilterDtos/BaseFilterDto.cs
new file mode 100644
index 0000000..7def809
--- /dev/null
+++ b/NetinaShop.Domain/Dtos/FilterDtos/BaseFilterDto.cs
@@ -0,0 +1,10 @@
+namespace NetinaShop.Domain.Dtos.FilterDtos;
+
+public class BaseFilterDto
+{
+ public string Name { get; set; } = string.Empty;
+ public string Type { get; set; } = string.Empty;
+ public string QueryName { get; set; } = string.Empty;
+ public QueryFilterType QueryType { get; set; }
+ public List Options { get; set; } = new List();
+}
\ No newline at end of file
diff --git a/NetinaShop.Domain/Dtos/FilterDtos/ExpressDeliveryFilter.cs b/NetinaShop.Domain/Dtos/FilterDtos/ExpressDeliveryFilter.cs
new file mode 100644
index 0000000..2f84c38
--- /dev/null
+++ b/NetinaShop.Domain/Dtos/FilterDtos/ExpressDeliveryFilter.cs
@@ -0,0 +1,13 @@
+namespace NetinaShop.Domain.Dtos.FilterDtos;
+
+public class ExpressDeliveryFilter : BaseFilterDto
+{
+ public ExpressDeliveryFilter()
+ {
+ Name = "ارسال سریع";
+ QueryName = "expressDelivery";
+ Type = "checkbox";
+ QueryType = QueryFilterType.Bool;
+ Options.Add(new FilterOptionDto{Id = 0,Title = "فقط ارسال سریع"});
+ }
+}
\ No newline at end of file
diff --git a/NetinaShop.Domain/Dtos/FilterDtos/FilterOptionDto.cs b/NetinaShop.Domain/Dtos/FilterDtos/FilterOptionDto.cs
new file mode 100644
index 0000000..b00f562
--- /dev/null
+++ b/NetinaShop.Domain/Dtos/FilterDtos/FilterOptionDto.cs
@@ -0,0 +1,7 @@
+namespace NetinaShop.Domain.Dtos.FilterDtos;
+
+public class FilterOptionDto
+{
+ public int Id { get; set; }
+ public string Title { get; set; } = string.Empty;
+}
\ No newline at end of file
diff --git a/NetinaShop.Domain/Dtos/FilterDtos/PriceFilterDto.cs b/NetinaShop.Domain/Dtos/FilterDtos/PriceFilterDto.cs
new file mode 100644
index 0000000..2dfc018
--- /dev/null
+++ b/NetinaShop.Domain/Dtos/FilterDtos/PriceFilterDto.cs
@@ -0,0 +1,15 @@
+namespace NetinaShop.Domain.Dtos.FilterDtos;
+
+public class PriceFilterDto : BaseFilterDto
+{
+ public PriceFilterDto()
+ {
+ Name = "قیمت";
+ QueryName = "minimumPrice";
+ Type = "slider";
+ QueryType = QueryFilterType.Int;
+ }
+
+ public double MinimumValue { get; set; }
+ public double MaximumValue { get; set; }
+}
\ No newline at end of file
diff --git a/NetinaShop.Domain/Dtos/ResponseDtos/GetProductsResponseDto.cs b/NetinaShop.Domain/Dtos/ResponseDtos/GetProductsResponseDto.cs
index e39e8b8..ecc2015 100644
--- a/NetinaShop.Domain/Dtos/ResponseDtos/GetProductsResponseDto.cs
+++ b/NetinaShop.Domain/Dtos/ResponseDtos/GetProductsResponseDto.cs
@@ -1,8 +1,18 @@
-namespace NetinaShop.Domain.Dtos.ResponseDtos;
+using NetinaShop.Domain.Dtos.FilterDtos;
+
+namespace NetinaShop.Domain.Dtos.ResponseDtos;
public class GetProductsResponseDto
{
public List Products { get; set; } = new List();
public PagerResponseDto Pager { get; set; } = new PagerResponseDto();
+
+ public FilterResponseDto Filters { get; set; } = new FilterResponseDto();
+}
+
+public class FilterResponseDto
+{
+ public PriceFilterDto Price { get; set; } = new PriceFilterDto();
+ public ExpressDeliveryFilter ExpressDelivery { get; set; } = new ExpressDeliveryFilter();
}
\ No newline at end of file
diff --git a/NetinaShop.Domain/Enums/QueryFilterType.cs b/NetinaShop.Domain/Enums/QueryFilterType.cs
new file mode 100644
index 0000000..8c38343
--- /dev/null
+++ b/NetinaShop.Domain/Enums/QueryFilterType.cs
@@ -0,0 +1,9 @@
+namespace NetinaShop.Domain.Enums;
+
+public enum QueryFilterType
+{
+ Int = 0,
+ String = 1,
+ Guid = 2,
+ Bool = 3,
+}
\ No newline at end of file
diff --git a/NetinaShop.Domain/NetinaShop.Domain.csproj b/NetinaShop.Domain/NetinaShop.Domain.csproj
index 41b085e..821ce48 100644
--- a/NetinaShop.Domain/NetinaShop.Domain.csproj
+++ b/NetinaShop.Domain/NetinaShop.Domain.csproj
@@ -36,6 +36,7 @@
+
diff --git a/NetinaShop.Repository/Behaviors/ValidationBehavior.cs b/NetinaShop.Repository/Behaviors/ValidationBehavior.cs
new file mode 100644
index 0000000..f4cdd1a
--- /dev/null
+++ b/NetinaShop.Repository/Behaviors/ValidationBehavior.cs
@@ -0,0 +1,34 @@
+using FluentValidation;
+using ValidationException = NetinaShop.Common.Models.Exception.ValidationException;
+
+namespace NetinaShop.Repository.Behaviors;
+
+public class ValidationBehavior : IPipelineBehavior where TRequest : notnull
+{
+ private readonly IEnumerable> _validators;
+
+ public ValidationBehavior(IEnumerable> validators)
+ {
+ _validators = validators;
+ }
+ public async Task Handle(TRequest request, RequestHandlerDelegate next, CancellationToken cancellationToken)
+ {
+ var context = new ValidationContext(request);
+ List errors = new List();
+ foreach (IValidator validator in _validators)
+ {
+ var result = await validator.ValidateAsync(context, cancellationToken);
+ if (!result.IsValid)
+ errors.AddRange(result.Errors.Select(v => new ValidationError(v.PropertyName, v.ErrorMessage)).Distinct());
+ }
+
+ if (errors.Any())
+ {
+ throw new ValidationException(errors);
+ }
+
+
+ var response = await next();
+ return response;
+ }
+}
\ No newline at end of file
diff --git a/NetinaShop.Repository/Handlers/Addresses/CreateAddressCommandHandler.cs b/NetinaShop.Repository/Handlers/Addresses/CreateAddressCommandHandler.cs
index d297889..205ed78 100644
--- a/NetinaShop.Repository/Handlers/Addresses/CreateAddressCommandHandler.cs
+++ b/NetinaShop.Repository/Handlers/Addresses/CreateAddressCommandHandler.cs
@@ -17,6 +17,7 @@ public class CreateAddressCommandHandler : IRequestHandler
+{
+ public CreateBrandCommandValidator()
+ {
+ RuleFor(r => r.PersianName)
+ .NotNull()
+ .NotEmpty()
+ .WithMessage("نام فارسی برند را وارد کنید");
+
+ RuleFor(r => r.EnglishName)
+ .NotNull()
+ .NotEmpty()
+ .WithMessage("نام انگلیسی برند را وارد کنید");
+ }
+}
\ No newline at end of file
diff --git a/NetinaShop.Repository/Handlers/Brands/Validators/UpdateBrandCommandValidator.cs b/NetinaShop.Repository/Handlers/Brands/Validators/UpdateBrandCommandValidator.cs
new file mode 100644
index 0000000..8b58175
--- /dev/null
+++ b/NetinaShop.Repository/Handlers/Brands/Validators/UpdateBrandCommandValidator.cs
@@ -0,0 +1,19 @@
+using FluentValidation;
+
+namespace NetinaShop.Repository.Handlers.Brands.Validators;
+
+public class UpdateBrandCommandValidator : AbstractValidator
+{
+ public UpdateBrandCommandValidator()
+ {
+ RuleFor(r => r.PersianName)
+ .NotNull()
+ .NotEmpty()
+ .WithMessage("نام فارسی برند را وارد کنید");
+
+ RuleFor(r => r.EnglishName)
+ .NotNull()
+ .NotEmpty()
+ .WithMessage("نام انگلیسی برند را وارد کنید");
+ }
+}
\ No newline at end of file
diff --git a/NetinaShop.Repository/Handlers/Complexes/Validators/CreateBrandCommandValidator.cs b/NetinaShop.Repository/Handlers/Complexes/Validators/CreateBrandCommandValidator.cs
new file mode 100644
index 0000000..3e889e2
--- /dev/null
+++ b/NetinaShop.Repository/Handlers/Complexes/Validators/CreateBrandCommandValidator.cs
@@ -0,0 +1,10 @@
+using FluentValidation;
+
+namespace NetinaShop.Repository.Handlers.Complexes.Validators;
+
+public class CreateOrUpdateComplexCommandValidator : AbstractValidator
+{
+ public CreateOrUpdateComplexCommandValidator()
+ {
+ }
+}
\ No newline at end of file
diff --git a/NetinaShop.Repository/Handlers/Discounts/Validators/CreateDiscountCommandValidator.cs b/NetinaShop.Repository/Handlers/Discounts/Validators/CreateDiscountCommandValidator.cs
new file mode 100644
index 0000000..4070d73
--- /dev/null
+++ b/NetinaShop.Repository/Handlers/Discounts/Validators/CreateDiscountCommandValidator.cs
@@ -0,0 +1,39 @@
+using FluentValidation;
+
+namespace NetinaShop.Repository.Handlers.Discounts.Validators;
+
+public class CreateDiscountCommandValidator : AbstractValidator
+{
+ public CreateDiscountCommandValidator()
+ {
+ RuleFor(d=>d.Type)
+ .Must((command, type) =>
+ {
+ if (type == DiscountType.Category)
+ {
+ if (command.CategoryId == default)
+ return false;
+ else
+ return true;
+ }
+
+ return true;
+ })
+ .WithMessage("برای تخفیف برروی دسته ها باید دسته مورد نظر را وارد کنید");
+
+ RuleFor(d => d.Type)
+ .Must((command, type) =>
+ {
+ if (type == DiscountType.Product)
+ {
+ if (command.ProductId == default)
+ return false;
+ else
+ return true;
+ }
+
+ return true;
+ })
+ .WithMessage("برای تخفیف برروی کالای خاص باید کالای مورد نظر را وارد کنید");
+ }
+}
\ No newline at end of file
diff --git a/NetinaShop.Repository/Handlers/Discounts/Validators/UpdateDiscountCommandValidator.cs b/NetinaShop.Repository/Handlers/Discounts/Validators/UpdateDiscountCommandValidator.cs
new file mode 100644
index 0000000..2f089e2
--- /dev/null
+++ b/NetinaShop.Repository/Handlers/Discounts/Validators/UpdateDiscountCommandValidator.cs
@@ -0,0 +1,39 @@
+using FluentValidation;
+
+namespace NetinaShop.Repository.Handlers.Discounts.Validators;
+
+public class UpdateDiscountCommandValidator : AbstractValidator
+{
+ public UpdateDiscountCommandValidator()
+ {
+ RuleFor(d => d.Type)
+ .Must((command, type) =>
+ {
+ if (type == DiscountType.Category)
+ {
+ if (command.CategoryId == default)
+ return false;
+ else
+ return true;
+ }
+
+ return true;
+ })
+ .WithMessage("برای تخفیف برروی دسته ها باید دسته مورد نظر را وارد کنید");
+
+ RuleFor(d => d.Type)
+ .Must((command, type) =>
+ {
+ if (type == DiscountType.Product)
+ {
+ if (command.ProductId == default)
+ return false;
+ else
+ return true;
+ }
+
+ return true;
+ })
+ .WithMessage("برای تخفیف برروی کالای خاص باید کالای مورد نظر را وارد کنید");
+ }
+}
\ No newline at end of file
diff --git a/NetinaShop.Repository/Handlers/Newsletters/Validators/CreateNewsletterMemberCommandValidator.cs b/NetinaShop.Repository/Handlers/Newsletters/Validators/CreateNewsletterMemberCommandValidator.cs
new file mode 100644
index 0000000..77e69d8
--- /dev/null
+++ b/NetinaShop.Repository/Handlers/Newsletters/Validators/CreateNewsletterMemberCommandValidator.cs
@@ -0,0 +1,28 @@
+using FluentValidation;
+using Microsoft.IdentityModel.Tokens;
+
+namespace NetinaShop.Repository.Handlers.Newsletters.Validators;
+
+public class CreateNewsletterMemberCommandValidator : AbstractValidator
+{
+ public CreateNewsletterMemberCommandValidator()
+ {
+ RuleFor(command => command)
+ .Must(command =>
+ {
+ if (command.PhoneNumber.IsNullOrEmpty() && command.Email.IsNullOrEmpty())
+ return false;
+ return true;
+ })
+ .WithMessage("شماره تلفن یا ایمیل را باید وارد کنید");
+
+ RuleFor(c=>c.PhoneNumber)
+ .Must(phoneNumber =>
+ {
+ if(phoneNumber.IsNullOrEmpty()) return true;
+
+ return PhoneNumberExtensions.CheckPhoneNumber(phoneNumber);
+ })
+ .WithMessage("شماره تلفن ارسالی اشتباه است");
+ }
+}
\ No newline at end of file
diff --git a/NetinaShop.Repository/Handlers/ProductCategories/CreateProductCategoryCommandHandler.cs b/NetinaShop.Repository/Handlers/ProductCategories/CreateProductCategoryCommandHandler.cs
index ae441cf..de6693f 100644
--- a/NetinaShop.Repository/Handlers/ProductCategories/CreateProductCategoryCommandHandler.cs
+++ b/NetinaShop.Repository/Handlers/ProductCategories/CreateProductCategoryCommandHandler.cs
@@ -10,6 +10,7 @@ public class CreateProductCategoryCommandHandler : IRequestHandler Handle(CreateProductCategoryCommand request, CancellationToken cancellationToken)
{
var ent = ProductCategory.Create(request.Name, request.Description, request.IsMain);
diff --git a/NetinaShop.Repository/Handlers/ProductCategories/Validators/CreateProductCategoryCommandValidator.cs b/NetinaShop.Repository/Handlers/ProductCategories/Validators/CreateProductCategoryCommandValidator.cs
new file mode 100644
index 0000000..792295d
--- /dev/null
+++ b/NetinaShop.Repository/Handlers/ProductCategories/Validators/CreateProductCategoryCommandValidator.cs
@@ -0,0 +1,14 @@
+using FluentValidation;
+
+namespace NetinaShop.Repository.Handlers.ProductCategories.Validators;
+
+public class CreateProductCategoryCommandValidator : AbstractValidator
+{
+ public CreateProductCategoryCommandValidator()
+ {
+ RuleFor(d=>d.Name)
+ .NotNull()
+ .NotEmpty()
+ .WithMessage("نام دسته بندی مورد نظر را وارد کنید");
+ }
+}
\ No newline at end of file
diff --git a/NetinaShop.Repository/Handlers/ProductCategories/Validators/UpdateProductCategoryCommandValidator.cs b/NetinaShop.Repository/Handlers/ProductCategories/Validators/UpdateProductCategoryCommandValidator.cs
new file mode 100644
index 0000000..df28abc
--- /dev/null
+++ b/NetinaShop.Repository/Handlers/ProductCategories/Validators/UpdateProductCategoryCommandValidator.cs
@@ -0,0 +1,14 @@
+using FluentValidation;
+
+namespace NetinaShop.Repository.Handlers.ProductCategories.Validators;
+
+public class UpdateProductCategoryCommandValidator : AbstractValidator
+{
+ public UpdateProductCategoryCommandValidator()
+ {
+ RuleFor(d => d.Name)
+ .NotNull()
+ .NotEmpty()
+ .WithMessage("نام دسته بندی مورد نظر را وارد کنید");
+ }
+}
\ No newline at end of file
diff --git a/NetinaShop.Repository/Handlers/Products/GetProductsQueryHandler.cs b/NetinaShop.Repository/Handlers/Products/GetProductsQueryHandler.cs
index b3d5d06..6e2cdf3 100644
--- a/NetinaShop.Repository/Handlers/Products/GetProductsQueryHandler.cs
+++ b/NetinaShop.Repository/Handlers/Products/GetProductsQueryHandler.cs
@@ -72,6 +72,11 @@ public class GetProductsQueryHandler : IRequestHandler p.Cost,cancellationToken);
+ response.Filters.Price.MinimumValue = await products.MinAsync(p => p.Cost,cancellationToken);
+
+
+
foreach (var productSDto in productSDtos)
{
await _mediator.Send(new CalculateProductDiscountCommand(productSDto), cancellationToken);
diff --git a/NetinaShop.Repository/Handlers/Products/Validators/CreateProductCommandValidator.cs b/NetinaShop.Repository/Handlers/Products/Validators/CreateProductCommandValidator.cs
new file mode 100644
index 0000000..29b9942
--- /dev/null
+++ b/NetinaShop.Repository/Handlers/Products/Validators/CreateProductCommandValidator.cs
@@ -0,0 +1,34 @@
+using FluentValidation;
+
+namespace NetinaShop.Repository.Handlers.Products.Validators;
+
+public class CreateProductCommandValidator : AbstractValidator
+{
+ public CreateProductCommandValidator()
+ {
+ RuleFor(d => d.PersianName)
+ .NotNull()
+ .NotEmpty()
+ .WithMessage("نام فارسی کالا مورد نظر را وارد کنید");
+
+ RuleFor(d => d.EnglishName)
+ .NotNull()
+ .NotEmpty()
+ .WithMessage("نام انگلیسی کالا مورد نظر را وارد کنید");
+
+ RuleFor(d => d.Summery)
+ .NotNull()
+ .NotEmpty()
+ .WithMessage("توضیحات کوتاه کالا مورد نظر را وارد کنید");
+
+ RuleFor(d => d.CategoryId)
+ .NotEqual(Guid.Empty)
+ .NotEmpty()
+ .WithMessage("دسته بندی کالا مورد نظر را وارد کنید");
+
+ RuleFor(d => d.BrandId)
+ .NotEqual(Guid.Empty)
+ .NotEmpty()
+ .WithMessage("برند کالا مورد نظر را وارد کنید");
+ }
+}
\ No newline at end of file
diff --git a/NetinaShop.Repository/Handlers/Products/Validators/UpdateProductCommandValidator.cs b/NetinaShop.Repository/Handlers/Products/Validators/UpdateProductCommandValidator.cs
new file mode 100644
index 0000000..2948598
--- /dev/null
+++ b/NetinaShop.Repository/Handlers/Products/Validators/UpdateProductCommandValidator.cs
@@ -0,0 +1,34 @@
+using FluentValidation;
+
+namespace NetinaShop.Repository.Handlers.Products.Validators;
+
+public class UpdateProductCommandValidator : AbstractValidator
+{
+ public UpdateProductCommandValidator()
+ {
+ RuleFor(d => d.PersianName)
+ .NotNull()
+ .NotEmpty()
+ .WithMessage("نام فارسی کالا مورد نظر را وارد کنید");
+
+ RuleFor(d => d.EnglishName)
+ .NotNull()
+ .NotEmpty()
+ .WithMessage("نام انگلیسی کالا مورد نظر را وارد کنید");
+
+ RuleFor(d => d.Summery)
+ .NotNull()
+ .NotEmpty()
+ .WithMessage("توضیحات کوتاه کالا مورد نظر را وارد کنید");
+
+ RuleFor(d => d.CategoryId)
+ .NotEqual(Guid.Empty)
+ .NotEmpty()
+ .WithMessage("دسته بندی کالا مورد نظر را وارد کنید");
+
+ RuleFor(d => d.BrandId)
+ .NotEqual(Guid.Empty)
+ .NotEmpty()
+ .WithMessage("برند کالا مورد نظر را وارد کنید");
+ }
+}
\ No newline at end of file
diff --git a/NetinaShop.Repository/Handlers/Reviews/Validators/CreateReviewCommandValidator.cs b/NetinaShop.Repository/Handlers/Reviews/Validators/CreateReviewCommandValidator.cs
new file mode 100644
index 0000000..6f602ba
--- /dev/null
+++ b/NetinaShop.Repository/Handlers/Reviews/Validators/CreateReviewCommandValidator.cs
@@ -0,0 +1,24 @@
+using FluentValidation;
+
+namespace NetinaShop.Repository.Handlers.Reviews.Validators;
+
+public class CreateReviewCommandValidator : AbstractValidator
+{
+ public CreateReviewCommandValidator()
+ {
+ RuleFor(d => d.Title)
+ .NotNull()
+ .NotEmpty()
+ .WithMessage("عنوان نظر مورد نظر را وارد کنید");
+
+ RuleFor(d => d.Comment)
+ .NotNull()
+ .NotEmpty()
+ .WithMessage("متن نظر مورد نظر را وارد کنید");
+
+ RuleFor(d => d.ProductId)
+ .NotEqual(Guid.Empty)
+ .NotEmpty()
+ .WithMessage("کالا مورد نظر را وارد کنید");
+ }
+}
\ No newline at end of file
diff --git a/NetinaShop.Repository/Handlers/Reviews/Validators/UpdateReviewCommandValidator.cs b/NetinaShop.Repository/Handlers/Reviews/Validators/UpdateReviewCommandValidator.cs
new file mode 100644
index 0000000..1f7aa29
--- /dev/null
+++ b/NetinaShop.Repository/Handlers/Reviews/Validators/UpdateReviewCommandValidator.cs
@@ -0,0 +1,24 @@
+using FluentValidation;
+
+namespace NetinaShop.Repository.Handlers.Reviews.Validators;
+
+public class UpdateReviewCommandValidator : AbstractValidator
+{
+ public UpdateReviewCommandValidator()
+ {
+ RuleFor(d => d.Title)
+ .NotNull()
+ .NotEmpty()
+ .WithMessage("عنوان نظر مورد نظر را وارد کنید");
+
+ RuleFor(d => d.Comment)
+ .NotNull()
+ .NotEmpty()
+ .WithMessage("متن نظر مورد نظر را وارد کنید");
+
+ RuleFor(d => d.ProductId)
+ .NotEqual(Guid.Empty)
+ .NotEmpty()
+ .WithMessage("کالا مورد نظر را وارد کنید");
+ }
+}
\ No newline at end of file
diff --git a/NetinaShop.Repository/Handlers/Warehouses/Validators/CreateShippingCommandValidator.cs b/NetinaShop.Repository/Handlers/Warehouses/Validators/CreateShippingCommandValidator.cs
new file mode 100644
index 0000000..873fa1a
--- /dev/null
+++ b/NetinaShop.Repository/Handlers/Warehouses/Validators/CreateShippingCommandValidator.cs
@@ -0,0 +1,23 @@
+using FluentValidation;
+
+namespace NetinaShop.Repository.Handlers.Warehouses.Validators;
+
+public class CreateShippingCommandValidator : AbstractValidator
+{
+ public CreateShippingCommandValidator()
+ {
+ RuleFor(d => d.Name)
+ .NotNull()
+ .NotEmpty()
+ .WithMessage("نام روش ارسال مورد نظر را وارد کنید");
+
+ RuleFor(d => d.WarehouseName)
+ .NotNull()
+ .NotEmpty()
+ .WithMessage("انبار ارسال مورد نظر را وارد کنید");
+
+ RuleFor(d => d.DeliveryCost)
+ .GreaterThan(0)
+ .WithMessage("هزینه روش ارسال مورد نظر را وارد کنید");
+ }
+}
\ No newline at end of file
diff --git a/NetinaShop.Repository/Handlers/Warehouses/Validators/UpdateShippingCommandValidator.cs b/NetinaShop.Repository/Handlers/Warehouses/Validators/UpdateShippingCommandValidator.cs
new file mode 100644
index 0000000..f99bfd9
--- /dev/null
+++ b/NetinaShop.Repository/Handlers/Warehouses/Validators/UpdateShippingCommandValidator.cs
@@ -0,0 +1,23 @@
+using FluentValidation;
+
+namespace NetinaShop.Repository.Handlers.Warehouses.Validators;
+
+public class UpdateShippingCommandValidator : AbstractValidator
+{
+ public UpdateShippingCommandValidator()
+ {
+ RuleFor(d => d.Name)
+ .NotNull()
+ .NotEmpty()
+ .WithMessage("نام روش ارسال مورد نظر را وارد کنید");
+
+ RuleFor(d => d.WarehouseName)
+ .NotNull()
+ .NotEmpty()
+ .WithMessage("انبار ارسال مورد نظر را وارد کنید");
+
+ RuleFor(d => d.DeliveryCost)
+ .GreaterThan(0)
+ .WithMessage("هزینه روش ارسال مورد نظر را وارد کنید");
+ }
+}
\ No newline at end of file
diff --git a/NetinaShop.Repository/NetinaShop.Repository.csproj b/NetinaShop.Repository/NetinaShop.Repository.csproj
index d0657a5..7d06a92 100644
--- a/NetinaShop.Repository/NetinaShop.Repository.csproj
+++ b/NetinaShop.Repository/NetinaShop.Repository.csproj
@@ -29,8 +29,6 @@
-
-