Compare commits

..

47 Commits

Author SHA1 Message Date
Amir Hossein Khademi 81b78d16d0 Merge branch 'master' of https://git.vnfco.ir/NetinaShop/Api 2025-04-29 19:39:31 +03:30
Amir Hossein Khademi d283681c7c Enhance dialog functionality and UI components
- Updated `DiscountActionDialogBoxViewModel` to include asynchronous `SubmitCreateAsync` and `Cancel` methods.
- Added a new section in `PageActionDialogBox.razor` with a `MudStack` for adding sections, removing the previous grid layout.
- Improved `PageActionDialogBox.razor.cs` with new methods for adding and editing sections, enhancing error handling and dialog management.
- Refined `app.min.css` by removing redundant CSS properties for better style application.
- Created a new dialog in `PageSectionActionDialogBox.razor` for managing section details, including fields for title, button text, and URL.
- Introduced a new view model in `PageSectionActionDialogBox.razor.cs` to handle section dialog logic, including item addition and file selection.
- Updated `BasePageSection` class in `BasePage.cs` to manage multiple `SectionItem` objects.
- Modified project files (`Netina.Common.csproj` and `Netina.Domain.csproj`) to update the target framework and package references for compatibility.
2025-04-29 19:38:46 +03:30
Amir Hossein Khademi e45d48d8b3 ♻️ Cleanup and UI updates; version bump in project files
- 🔥 Removed unused `using` directives in `PageActionDialogBox.razor.cs`.
- 💄 Updated `MudItem` column widths in `SubProductActionDialogBox.razor`.
- 🆙 Bumped `AssemblyVersion` and `FileVersion` in `Netina.AdminPanel.PWA.csproj`.
- 🆙 Bumped `AssemblyVersion` and `FileVersion` in `Netina.Api.csproj`.
- 🛠️ Improved layout for `MudSelect` and `MudTextField` components.
- 🧹 Reduced unnecessary dependencies for better code readability.
- 🚀 Prepared for new release with updated project versioning.
- 📐 Adjusted UI spacing for better alignment on larger screens.
- 🔧 General maintenance and improvements in `.csproj` files.

Changes made by Amir.h Khademi
2025-04-18 20:48:57 +03:30
Amir Hossein Khademi 48d3386233 Add brand-specific discount feature
-  Add `MudAutocomplete` for brand selection in UI
  Introduced a new component in `DiscountActionDialogBox.razor`.
- 🆕 Introduce `IsBrandEnable` property in ViewModel
  Added to manage the state of brand-specific discounts.
- 🔄 Update ViewModel logic for `IsBrandEnable`
  Ensured mutual exclusivity with other discount types.
- 🛠️ Handle brand selection in `SubmitEditAsync`
  Added logic for brand selection and validation.
- 🔍 Modify `SearchBrand` method in ViewModel
  Fetch and return brand data for selection.
- 📦 Change target framework to `net5.0`
  Updated `Netina.Common.csproj` and `Netina.Domain.csproj`.
- 🆙 Update `UpdateDiscountCommand` and `DiscountLDto`
  Included `BrandId` and `BrandName` properties.
- 🛠️ Modify `UpdateDiscountCommandHandler`
  Handle brand-specific discount updates.
- 🆕 Add `SubmitEditAsync` method in ViewModel
  For handling discount edits.

Changes made by Amir.H Khademi
2025-04-14 18:02:07 +03:30
Amir Hossein Khademi 13751e452a Add DiversitySecondaryValue to SubProduct
- 🖼️ Update SubProductActionDialogBox.razor layout
  Adjust grid item sizes and add new input field for DiversitySecondaryValue.
- 🧑‍💻 Update SubProductActionDialogBoxViewModel
  Include DiversitySecondaryValue parameter in command constructors.
- 📈 Increment version in Netina.AdminPanel.PWA.csproj
  Update AssemblyVersion and FileVersion to 1.12.22.38.
- 🆕 Add BrandDiscountMapper.g.cs
  Introduce static partial class BrandDiscountMapper in Netina.Domain.Mappers.
- 🗃️ Add migration 20250414120653_EditSubProductValue.cs
  Add DiversitySecondaryValue column to Products table.
- 🏷️ Update SubProduct related classes and methods
  Add DiversitySecondaryValue property to CreateSubProductCommand, UpdateSubProductCommand, and SubProductSDto.
- 🛠️ Modify command handlers
  Update CreateSubProductCommandHandler and UpdateSubProductCommandHandler to handle DiversitySecondaryValue.
- 🗄️ Update Product.Aggregate.cs and SubProduct.cs
  Include DiversitySecondaryValue property in SubProduct class.
- 🔄 Update SubProductMapper.g.cs
  Map DiversitySecondaryValue property in SubProductMapper.

Changes made by Amir.H Khademi
2025-04-14 15:43:49 +03:30
Amir Hossein Khademi 1d29f39cbc Add BrandId columns and update project framework
*  Introduce `EditDisc` migration in `NetinaShop.Repository.Migrations`
* 🗃️ Add `BrandId` column to `OrderProducts` and `Discounts` tables
* 🛠️ Set default value for `BrandId` in `OrderProducts` to `00000000-0000-0000-0000-000000000000`
* 🗃️ Make `BrandId` in `Discounts` nullable
* 🏷️ Create index on `BrandId` in `Discounts` table
* 🔗 Add foreign key constraint from `Discounts` to `Brands` on `BrandId`
* 🔄 Implement `Down` method to reverse migration changes
* ⬆️ Update target framework to `net8.0`
* 🔢 Increment `AssemblyVersion` and `FileVersion` in `Netina.Api.csproj`
* 🏷️ Add `BrandId` and `Count` properties to `ApplicationContextModelSnapshot.cs`
* 🆕 Add `BrandDiscount` entity inheriting from `Discount` with `BrandId` property

Changes made by Amir.h Khademi
2025-03-29 01:51:08 +03:30
Amir Hossein Khademi e445be641e Merge remote-tracking branch 'origin/subProduct' 2025-03-27 10:35:37 +03:30
Amir Hossein Khademi 5dc92f63e7 Enhance page management and dialog functionality
- `PageActionDialogBox.razor`: Add form fields and data grid
  Added fields for section title, button title, address, description, type, and query. Added button and data grid for sections.
- `PageActionDialogBox.razor.cs`: Add `InitializeAsync` method
  Added using directives, `InitializeAsync` method, `IsEditing` flag, and `PageId` property.
- `PagesManagementPage.razor`: Add edit button for pages
  Added edit button to trigger `EditPageAsync` method for each page.
- `PagesManagementPage.razor.cs`: Refactor for constructor injection
  Refactored to use constructor injection. Added `EditPageAsync` method and updated `RemovePageAsync` method.
- `IPageRestApi.cs`: Change return type of `ReadById` method
  Updated return type from `BasePageSDto` to `BasePageLDto`.

Changes made by Amir.H Khademi
2025-03-25 18:41:41 +03:30
Amir Hossein Khademi 6da620690d Update page handling, dependencies, and UI components
*  Added `default` parameter to `DiscountActionDialogBoxViewModel`
* 🔧 Updated `@inject` in `ShippingActionDialogBox.razor` with new services
* ⬆️ Upgraded dependencies in `package-lock.json` and `package.json`
* 📝 Changed `IsShop` setting in `appsettings.Production.json` to `true`
* 💄 Updated `app.min.css` for Tailwind CSS v3.4.17 changes
* 🆕 Added `PageActionDialogBox.razor` and `PageActionDialogBox.razor.cs`
* 🆕 Introduced `BasePageLDto` class for detailed page info
* 🚀 Added `MapPost` endpoint for updating pages in `PageController.cs`
* 🔄 Refactored methods in `PageController.cs` for conciseness
* 🛠️ Updated `IPageService` and `PageService` with `UpdatePageAsync`
* 🗂️ Enhanced `SiteMapService` to filter pages by `Indexing`
* 🛒 Included `BrandId` in order bag commands

Changes made by Amir.h Khademi
2025-03-23 11:04:45 +03:30
Amir Hossein Khademi 96feec0b26 Add support for brand-based discounts
* 🆕 Added support for brand discounts in `CalculateOrderDiscountCommandHandler`
* 🏷️ Updated `DiscountCommands` class to include `BrandId` property
* 🏗️ Introduced `BrandDiscount` class in `Discount.Aggregate.cs` with `Create` method
* 🛠️ Modified `Order` class in `Order.Aggregate.cs` to handle `BrandId`
* 🏷️ Updated `OrderProduct` class in `Order.Aggregate.cs` to include `BrandId` property
* 🆕 Added `Brand` discount type to `DiscountType` enum
*  Enhanced `CreateDiscountCommandHandler` and `UpdateDiscountCommandHandler` for brand discounts
* 🆕 Introduced `BrandDiscount` class in `BrandDiscount.cs` to represent brand-specific discounts

Changes made by Amir.h Khademi
2025-03-23 09:40:55 +03:30
Amir Hossein Khademi a87bfee340 free shiping 2025-02-11 14:22:42 +03:30
Amir Hossein Khademi 7d94e8cd47 Add sub-product management feature
Introduced a new feature for managing sub-products within the application. This includes:

- Added a new tab panel for "Sub Products" in `ProductActionDialogBox.razor`.
- Created `SubProductActionDialogBox` component for sub-product creation and editing.
- Updated `ProductActionDialogBoxViewModel` to handle sub-product operations.
- Modified `Address` class and `IProductRestApi` interface to support sub-products.
- Added `SubProductController` for API requests related to sub-products.
- Introduced command and query classes for sub-product operations.
- Created `SubProductSDto` for sub-product data transfer.
- Added `SubProduct` class inheriting from `Product` with additional properties.
- Introduced `ProductDiversity` and `ColorDiversity` enums.
- Added `SubProductMapper` for mapping between `SubProduct` and `SubProductSDto`.
- Implemented command handlers for sub-product CRUD operations.
- Added migration script `20241217212716_AddSubProduct` to update the database schema.
- Updated `ProductController`, `SiteMapService`, and `Product` class to support sub-products.
- Added `SubProductActionDialogBox.razor` for sub-product UI management.
2024-12-18 02:14:07 +03:30
Amir Hossein Khademi 559ab04d9b Add MetaTags support and update project configurations
- Removed unused @using directives in App.razor and BrandsPage.razor.
- Added UI elements for meta tags in BrandActionDialogBox.razor.
- Updated BrandActionDialogBoxViewModel to handle meta tags.
- Changed label text in DiscountActionDialogBox.razor.
- Updated assembly and file versions in Netina.AdminPanel.PWA.csproj.
- Added BlogMetaTag and BrandMetaTag classes.
- Added migration to update database schema for meta tags.
- Updated BlogController to handle meta tags.
- Set LangVersion to latest in multiple project files.
- Changed array initialization syntax in various files.
- Added MetaTags property to BlogLDto and BrandLDto classes.
- Updated Blog and Brand classes to handle meta tags.
- Refactored mappers to include meta tags handling.
- Improved product sorting in GetProductsQueryHandler.cs.
- Updated ApplicationContextModelSnapshot for new entities.
2024-12-11 00:25:26 +03:30
Amir Hossein Khademi 53dc2eac0c Refactor and enhance product and order handling
- Updated `DiscountActionDialogBoxViewModel` and `FastProductCreateDialogBoxViewModel` to create command objects directly from properties and improved error handling.
- Added meta tag management UI and logic in `ProductActionDialogBox.razor` and `ProductActionDialogBoxViewModel`.
- Increased max file read stream size to 8 MB in `StorageDialogBoxViewModel`.
- Incremented `AssemblyVersion` and `FileVersion` to `1.7.20.34` in `Netina.AdminPanel.PWA.csproj`.
- Updated `BrandsPage.razor` and `BrandsPageViewModel` for pagination and service injection.
- Updated `CategoriesPageViewModel` to create command objects directly from properties.
- Updated `ProductsPage.razor` for service injection and added a button for product details.
- Updated `ICrudApiRest` and `ICrudDtoApiRest` interfaces to use generic `Create` methods.
- Updated `appsettings.Development.json` for `StorageBaseUrl` and commented out `IsShop`.
- Added new project `AppHost.csproj` targeting .NET 8.0 with Aspire hosting.
- Added new `appsettings.Development.json` and `appsettings.json` for logging.
- Added new `Program.cs` to create and run a distributed application.
- Added new `launchSettings.json` for application launch settings.
- Added `Extensions.cs` for common .NET Aspire services.
- Added new project `ServiceDefaults.csproj` for shared service defaults.
- Introduced `ProductMetaTag` class and related migration for meta tag handling.
- Updated `OrderController.cs` for additional authorization requirements.
- Updated target frameworks to `net8.0` in various projects.
- Enhanced `SiteMapService.cs` to include brand site maps.
- Added new properties to DTOs for customer and meta tag handling.
- Enhanced `Product` class with meta tag management methods.
- Refactored `OrderMapper.g.cs` and `ProductMapper.g.cs` for improved mapping logic.
- Enhanced command handlers to manage meta tags.
- Added `ICurrentUserService` for user permissions in query handlers.
- Refactored `StorageService.cs` for paginated storage file fetching.
2024-12-06 17:37:41 +03:30
Amir Hossein Khademi 82f9d604da feat(MetaTags) , feat(ProductCategoryMetaTags) , VER 1.6.18.28 2024-10-25 14:36:19 +03:30
Amir Hossein Khademi d17422d646 fix marten 2024-10-10 22:12:46 +03:30
Amir Hossein Khademi 738a4d523c fix (SiteMapWhiteSpace) VER 1.5.18.27 2024-10-04 20:36:14 +03:30
Amir Hossein Khademi cfb293c135 fix calculate issue 2024-09-30 22:09:39 +03:30
Amir Hossein Khademi a1f2e92863 fix(CateforyDiscount) , fix(ProductReviewCountInDTos) , VER 1.5.17.23 2024-09-29 12:31:08 +03:30
Amir Hossein Khademi c3abc322d4 feat(ReviewActionDialog) , VER 1.5.14.20 2024-09-27 14:14:33 +03:30
Amir Hossein Khademi 908424f9be change to comment 2024-09-25 17:08:35 +03:30
Amir Hossein Khademi ca934aecc8 Update Packages 2024-09-24 14:03:16 +03:30
Amir Hossein Khademi 6bd9066f8d Change to comment PHASE A 2024-09-24 00:34:53 +03:30
Amir Hossein Khademi 28ffed532d fix(ReviewEntity) , VER 1.4.14.19 2024-09-21 20:51:01 +03:30
Amir Hossein Khademi 56e8e3e1d9 Merge branch 'master' of https://git.vnfco.ir/NetinaShop/Api 2024-09-11 19:59:59 +03:30
Amir Hossein Khademi ea4f17a5d9 merge 2024-09-11 19:59:51 +03:30
Amir Hossein Khademi 8e5003028d add auuthor 2024-09-11 19:59:27 +03:30
Amir Hossein Khademi fda7088abb feat ( ReviewEntitiy )
- Add review entity and CQRS
2024-09-01 12:28:42 +03:30
Amir Hossein Khademi 2e8501190e fix (ControllerMethodsDescription) , fix(SlugExtension) 2024-08-16 18:27:54 +03:30
Amir Hossein Khademi be6f462708 VER 1.2.11.13 2024-08-10 20:36:10 +03:30
Amir Hossein Khademi d59657c1bf fix(SearchProductByName) 2024-08-10 20:35:38 +03:30
Amir Hossein Khademi ae9b65adbd fix files 2024-08-09 21:55:16 +03:30
Amir Hossein Khademi 19f1f29548 feat(FaqInActions) , feat(FaqManagementPage) , feat(FaqController) 2024-08-07 16:15:53 +03:30
Amir Hossein Khademi 5524cb4e43 feat(AddBanner) , feat(AddCatelog) , feat(AddPersonalizationPage) 2024-08-06 14:26:39 +03:30
Amir Hossein Khademi e9764c6cd4 feat(AddFastPriceChange) 2024-08-06 12:38:57 +03:30
Amir Hossein Khademi 8f28afbf50 fix(CKEditor) , fix(DiscountDuplicateCode) 2024-08-06 11:39:21 +03:30
Amir Hossein Khademi 1137fde70b fix(CancelOrder) 2024-08-06 10:30:01 +03:30
Amir Hossein Khademi 8c7e09e5e6 fix(AmountSpecialOffer) 2024-08-05 23:23:32 +03:30
Amir Hossein Khademi c519d9ac8c change scalar and packages 2024-07-31 12:59:03 +03:30
Amir Hossein Khademi e5f62f4b14 feat(ProductFilter)
- Add IsEnable filter in products page
2024-07-08 17:05:04 +03:30
Amir Hossein Khademi a66ee7c8a2 fix(TaxesFee) , fix(InvoiceWaterMark) , VER 1.0.9.11 2024-07-01 21:08:32 +03:30
Amir Hossein Khademi ab0f4a683c feat(TaxesFee)
- Add taxes fee
- Calculate taxes fee in calculate order command handler
2024-07-01 19:49:26 +03:30
Amir Hossein Khademi 95346be5f1 feat(AddFeatureFastProduct) , fix(CheckUserDiscount) , fix(SideBar)
- Add feature in fast product create dialog box
- Fix user fist use discount check user
- Fix sidebar
2024-06-24 22:32:44 +03:30
Amir Hossein Khademi fd0f5696f4 fix(no-scrollbar) , fix(OrdersPagePagination) , feat(ShowOrderBagQuery)
-Fix no-scrollbar in pages
-Fix orders page pageination at page 2
-Add show order bag query in GetOrders
2024-06-12 13:18:26 +03:30
Amir Hossein Khademi 4ff7601843 fix(CheckUserFirstDiscountUser)
-Add new command for CheckUserFirstDiscountUser
-Fix CheckUserFirstDiscountUser
2024-06-12 11:05:15 +03:30
Amir Hossein Khademi 5edd394252 fix(DiscountCode),VER 1.0.5.6
- Fix discount code use one time per user and customer
- Add Version 1.0.5.6
2024-06-11 18:14:47 +03:30
Amir Hossein Khademi da64ae5b40 fix(TorobGetProducts) , fix(EmallsProducts), VER 1.0.4.5
- Fix torob product price to Tooman
- Fix emalls product price to Tooman
- Add version 1.0.4.5
2024-06-11 12:55:02 +03:30
310 changed files with 29019 additions and 3944 deletions

View File

@ -1 +1 @@
1.0.3.3 1.10.21.36

View File

@ -1,8 +1,8 @@
{ {
"ConnectionStrings": { "ConnectionStrings": {
"PostgresServer": "Host=185.220.227.107;Username=vesmmehAgent;Password=g05CTjK358Vx3Eoc9satsWyVwo+15UmsA2dnCrZRUYh1pLTe;Database=NetinaShopDB;Application Name=NetinaShopApi", "PostgresServer": "Host=185.220.227.29;Username=vesmmehAgent;Password=g05CTjK358Vx3Eoc9satsWyVwo+15UmsA2dnCrZRUYh1pLTe;Database=NetinaShopDB;Application Name=NetinaShopApi",
"Postgres": "Host=pg-0,pg-1;Username=igarsonAgent;Password=xHTpBf4wC+bBeNg2pL6Ga7VEWKFJx7VPEUpqxwPFfOc2YYTVwFQuHfsiqoVeT9+6;Database=NetinaShopDB;Load Balance Hosts=true;Target Session Attributes=primary;Application Name=iGLS", "Postgres": "Host=pg-0;Username=postgres;Password=xHTpBf4wC+bBeNg2pL6Ga7VEWKFJx7VPEUpqxwPFfOc2YYTVwFQuHfsiqoVeT9+6;Database=NetinaShopDB",
"MartenDB": "Host=pg-0,pg-1;Username=igarsonAgent;Password=xHTpBf4wC+bBeNg2pL6Ga7VEWKFJx7VPEUpqxwPFfOc2YYTVwFQuHfsiqoVeT9+6;Database=NetinaShopMartenDB;" "MartenDB": "Host=pg-0;Username=postgres;Password=xHTpBf4wC+bBeNg2pL6Ga7VEWKFJx7VPEUpqxwPFfOc2YYTVwFQuHfsiqoVeT9+6;Database=NetinaShopMartenDB"
}, },
"Logging": { "Logging": {
"LogLevel": { "LogLevel": {

View File

@ -11,23 +11,26 @@ public class BlogCategoryController : ICarterModule
.MapGroup($"api/blog/category"); .MapGroup($"api/blog/category");
group.MapGet("", GetAllAsync) group.MapGet("", GetAllAsync)
.WithDisplayName("GetAllCategories") .WithDisplayName("Get BlogCategories")
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapGet("{id}", GetAsync) group.MapGet("{id}", GetAsync)
.WithDisplayName("GetBlogCategory") .WithDisplayName("Get BlogCategory")
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapPost("", Post) group.MapPost("", Post)
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission,ApplicationPermission.ManageBlogs)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission,ApplicationPermission.ManageBlogs))
.WithDisplayName("Create BlogCategory")
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapPut("", Put) group.MapPut("", Put)
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageBlogs)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageBlogs))
.WithDisplayName("Update BlogCategory")
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapDelete("{id}", Delete) group.MapDelete("{id}", Delete)
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageBlogs)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageBlogs))
.WithDisplayName("Delete BlogCategory")
.HasApiVersion(1.0); .HasApiVersion(1.0);
} }

View File

@ -1,8 +1,7 @@
using Marten.Events; using Microsoft.Extensions.Options;
using Microsoft.Extensions.Options;
using Netina.Domain.Entities.Blogs; using Netina.Domain.Entities.Blogs;
using Netina.Domain.Entities.Products;
using System.Web; using System.Web;
using Netina.Repository.Abstracts;
namespace Netina.Api.Controllers; namespace Netina.Api.Controllers;
@ -15,37 +14,48 @@ public class BlogController : ICarterModule
.MapGroup($"api/blog"); .MapGroup($"api/blog");
group.MapGet("", GetAllAsync) group.MapGet("", GetAllAsync)
.WithDisplayName("GetAllBlogs") .WithDisplayName("Get Blogs")
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapGet("{id}", GetAsync) group.MapGet("{id}", GetAsync)
.WithDisplayName("GetBlog") .WithDisplayName("Get Blog")
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapPost("", Post) group.MapPost("", Post)
.RequireAuthorization(builder => .RequireAuthorization(builder =>
builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser() builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser()
.RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageBlogs)) .RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageBlogs))
.WithDisplayName("Create Blog")
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapPut("", Put) group.MapPut("", Put)
.RequireAuthorization(builder => .RequireAuthorization(builder =>
builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser() builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser()
.RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageBlogs)) .RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageBlogs))
.WithDisplayName("Update Blog")
.HasApiVersion(1.0);
group.MapGet("{blogId}/comment", GetBlogCommentsAsync)
.WithDisplayName("Get Blog Comments")
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapDelete("{id}", Delete) group.MapDelete("{id}", Delete)
.RequireAuthorization(builder => .RequireAuthorization(builder =>
builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser() builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser()
.RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageBlogs)) .RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageBlogs))
.WithDisplayName("Delete Blog")
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapGet("/newlink", GetBlogNewLinkAsync) group.MapGet("/newlink", GetBlogNewLinkAsync)
.WithDisplayName("GetBlogNewLink") .WithDisplayName("Get Blog NewLink")
.HasApiVersion(1.0); .HasApiVersion(1.0);
} }
private async Task<IResult> GetBlogCommentsAsync([FromQuery] int page, [FromQuery] int count, [FromRoute] Guid blogId, IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new GetCommentsQuery(page, count, null, blogId), cancellationToken));
private async Task<IResult> GetBlogNewLinkAsync([FromQuery]string slug,IRepositoryWrapper repositoryWrapper,IOptionsSnapshot<SiteSettings> snapshot,CancellationToken cancellationToken) private async Task<IResult> GetBlogNewLinkAsync([FromQuery]string slug,IRepositoryWrapper repositoryWrapper,IOptionsSnapshot<SiteSettings> snapshot,CancellationToken cancellationToken)
{ {
var htmlSlug = HttpUtility.UrlEncode(slug); var htmlSlug = HttpUtility.UrlEncode(slug);
@ -76,13 +86,19 @@ public class BlogController : ICarterModule
} }
// POST:Create Entity // POST:Create Entity
public async Task<IResult> Post([FromBody] BlogLDto dto, IRepositoryWrapper repositoryWrapper, CancellationToken cancellationToken) public async Task<IResult> Post([FromBody] BlogLDto dto, IRepositoryWrapper repositoryWrapper,ICurrentUserService currentUserService, CancellationToken cancellationToken)
{ {
var ent = Blog.Create(dto.Title, dto.Content, dto.Tags, dto.ReadingTime, dto.Summery, dto.IsSuggested,dto.CategoryId); if (currentUserService.UserId == null)
throw new BaseApiException(ApiResultStatusCode.UnAuthorized, "User id is wrong");
if (!Guid.TryParse(currentUserService.UserId, out Guid userId))
throw new BaseApiException(ApiResultStatusCode.UnAuthorized, "User id is wrong");
var ent = Blog.Create(dto.Title, dto.Content, dto.Tags, dto.ReadingTime, dto.Summery, dto.IsSuggested,dto.CategoryId, userId);
foreach (var file in dto.Files) foreach (var file in dto.Files)
{ {
ent.AddFile(file.Name, file.FileLocation, file.FileName, file.IsHeader, file.IsPrimary, file.FileType); ent.AddFile(file.Name, file.FileLocation, file.FileName, file.IsHeader, file.IsPrimary, file.FileType);
} }
foreach (var item in dto.MetaTags)
ent.AddMetaTag(item.Type, item.Value);
repositoryWrapper.SetRepository<Blog>().Add(ent); repositoryWrapper.SetRepository<Blog>().Add(ent);
await repositoryWrapper.SaveChangesAsync(cancellationToken); await repositoryWrapper.SaveChangesAsync(cancellationToken);
@ -90,13 +106,17 @@ public class BlogController : ICarterModule
} }
// PUT:Update Entity // PUT:Update Entity
public async Task<IResult> Put([FromBody] BlogLDto dto, IRepositoryWrapper repositoryWrapper, CancellationToken cancellationToken) public async Task<IResult> Put([FromBody] BlogLDto dto, IRepositoryWrapper repositoryWrapper, ICurrentUserService currentUserService, CancellationToken cancellationToken)
{ {
var ent = await repositoryWrapper.SetRepository<Blog>().TableNoTracking var ent = await repositoryWrapper.SetRepository<Blog>().TableNoTracking
.FirstOrDefaultAsync(b => b.Id == dto.Id, cancellationToken); .FirstOrDefaultAsync(b => b.Id == dto.Id, cancellationToken);
if (ent == null) if (ent == null)
throw new AppException("Blog not found"); throw new AppException("Blog not found");
var newEnt = Blog.Create(dto.Title, dto.Content, dto.Tags, dto.ReadingTime, dto.Summery, dto.IsSuggested, dto.CategoryId); if (currentUserService.UserId == null)
throw new BaseApiException(ApiResultStatusCode.UnAuthorized, "User id is wrong");
if (!Guid.TryParse(currentUserService.UserId, out Guid userId))
throw new BaseApiException(ApiResultStatusCode.UnAuthorized, "User id is wrong");
var newEnt = Blog.Create(dto.Title, dto.Content, dto.Tags, dto.ReadingTime, dto.Summery, dto.IsSuggested, dto.CategoryId, userId);
newEnt.Id = ent.Id; newEnt.Id = ent.Id;
newEnt.CreatedAt = ent.CreatedAt; newEnt.CreatedAt = ent.CreatedAt;
newEnt.CreatedBy = ent.CreatedBy; newEnt.CreatedBy = ent.CreatedBy;
@ -114,6 +134,21 @@ public class BlogController : ICarterModule
foreach (var file in dto.Files.Where(f => f.Id == default)) foreach (var file in dto.Files.Where(f => f.Id == default))
newEnt.AddFile(file.Name, file.FileLocation, file.FileName, file.IsHeader, file.IsPrimary, file.FileType); newEnt.AddFile(file.Name, file.FileLocation, file.FileName, file.IsHeader, file.IsPrimary, file.FileType);
//Check MetaTags
var dbMetaTags = await repositoryWrapper.SetRepository<BlogMetaTag>()
.TableNoTracking
.Where(f => f.BlogId == ent.Id)
.ToListAsync(cancellationToken);
foreach (var feature in dbMetaTags.Where(feature => dto.MetaTags.Any(f => f.Type == feature.Type) == false))
{
repositoryWrapper.SetRepository<BlogMetaTag>()
.Delete(feature);
await repositoryWrapper.SaveChangesAsync(cancellationToken);
}
foreach (var item in dto.MetaTags.Where(f => dbMetaTags.Any(dbf => dbf.Type == f.Type) == false))
newEnt.AddMetaTag(item.Type, item.Value);
repositoryWrapper.SetRepository<Blog>().Update(newEnt); repositoryWrapper.SetRepository<Blog>().Update(newEnt);
await repositoryWrapper.SaveChangesAsync(cancellationToken); await repositoryWrapper.SaveChangesAsync(cancellationToken);
return TypedResults.Ok(); return TypedResults.Ok();

View File

@ -11,23 +11,26 @@ public class BrandController : ICarterModule
.MapGroup($"api/brand"); .MapGroup($"api/brand");
group.MapGet("", GetAllAsync) group.MapGet("", GetAllAsync)
.WithDisplayName("GetAllBrands") .WithDisplayName("Get Brands")
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapGet("{id}", GetAsync) group.MapGet("{id}", GetAsync)
.WithDisplayName("GetBlogBrand") .WithDisplayName("Get Brand")
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapPost("", Post) group.MapPost("", Post)
.HasApiVersion(1.0) .HasApiVersion(1.0)
.WithDisplayName("Create Brand")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageBrands)); .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageBrands));
group.MapPut("", Put) group.MapPut("", Put)
.HasApiVersion(1.0) .HasApiVersion(1.0)
.WithDisplayName("Update Brand")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageBrands)); .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageBrands));
group.MapDelete("{id}", Delete) group.MapDelete("{id}", Delete)
.HasApiVersion(1.0) .HasApiVersion(1.0)
.WithDisplayName("Delete Brand")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageBrands)); .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageBrands));
} }

View File

@ -1,50 +1,50 @@
namespace Netina.Api.Controllers; namespace Netina.Api.Controllers;
public class ProductReviewController : ICarterModule public class CommentController : ICarterModule
{ {
public void AddRoutes(IEndpointRouteBuilder app) public void AddRoutes(IEndpointRouteBuilder app)
{ {
var group = app.NewVersionedApi("ProductReview") var group = app.NewVersionedApi("Comments")
.MapGroup("product/review"); .MapGroup("api/comment");
group.MapGet("{id}", GetAsync) group.MapGet("{id}", GetAsync)
.WithDisplayName("GetOneAsync") .WithDisplayName("Get Comment")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewAllReviews,ApplicationPermission.ManageReview)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewAllReviews,ApplicationPermission.ManageReview))
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapGet("", GetAllAsync) group.MapGet("", GetAllAsync)
.WithDisplayName("GetAllAsync") .WithDisplayName("Get Comments")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewAllReviews, ApplicationPermission.ManageReview)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewAllReviews, ApplicationPermission.ManageReview))
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapPost("", PostAsync) group.MapPost("", PostAsync)
.WithDisplayName("PostReview") .WithDisplayName("Create Comment")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageReview, ApplicationPermission.AddReview)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser())
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapPut("confirm/{id}", ConfirmAsync) group.MapPut("confirm/{id}", ConfirmAsync)
.WithDisplayName("ConfirmAsync") .WithDisplayName("Confirm Comment")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ConfirmReview, ApplicationPermission.ManageReview)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ConfirmReview, ApplicationPermission.ManageReview))
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapDelete("{id}", DeleteAsync) group.MapDelete("{id}", DeleteAsync)
.WithDisplayName("DeleteAsync") .WithDisplayName("Delete Comment")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageReview)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageReview))
.HasApiVersion(1.0); .HasApiVersion(1.0);
} }
public async Task<IResult> GetAllAsync([FromQuery] int page, IMediator mediator, CancellationToken cancellationToken) public async Task<IResult> GetAllAsync([FromQuery] int page, IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new GetReviewsQuery(page), cancellationToken)); => TypedResults.Ok(await mediator.Send(new GetCommentsQuery(page), cancellationToken));
public async Task<IResult> GetAsync(Guid id, IMediator mediator, CancellationToken cancellationToken) public async Task<IResult> GetAsync(Guid id, IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new GetReviewQuery(id), cancellationToken)); => TypedResults.Ok(await mediator.Send(new GetCommentQuery(id), cancellationToken));
public async Task<IResult> PostAsync(CreateReviewCommand request, IMediator mediator, CancellationToken cancellationToken) public async Task<IResult> PostAsync(CreateCommentCommand request, IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(request, cancellationToken)); => TypedResults.Ok(await mediator.Send(request, cancellationToken));
public async Task<IResult> ConfirmAsync(Guid id, IMediator mediator, CancellationToken cancellationToken) public async Task<IResult> ConfirmAsync(Guid id, IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new ConfirmReviewCommand(id), cancellationToken)); => TypedResults.Ok(await mediator.Send(new ConfirmCommentCommand(id), cancellationToken));
public async Task<IResult> DeleteAsync(Guid id, IMediator mediator, CancellationToken cancellationToken) public async Task<IResult> DeleteAsync(Guid id, IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new DeleteReviewCommand(id), cancellationToken)); => TypedResults.Ok(await mediator.Send(new DeleteCommentCommand(id), cancellationToken));
} }

View File

@ -0,0 +1,17 @@
namespace Netina.Api.Controllers;
public class CustomerController : ICarterModule
{
public void AddRoutes(IEndpointRouteBuilder app)
{
var group = app.NewVersionedApi("Customer").MapGroup("api/customer")
.RequireAuthorization(builder=>builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser());
group.MapGet("", GetCustomersAsync)
.WithDisplayName("Get Customers")
.HasApiVersion(1.0);
}
private async Task<IResult> GetCustomersAsync([FromQuery] int page, [FromQuery] int? count, [FromServices] IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(true);
}

View File

@ -15,8 +15,6 @@ public class DashboardController : ICarterModule
group.MapGet("orders", GetOrdersDashboardAsync) group.MapGet("orders", GetOrdersDashboardAsync)
.WithDisplayName("Get Orders Dashboard") .WithDisplayName("Get Orders Dashboard")
.HasApiVersion(1.0); .HasApiVersion(1.0);
} }
private async Task<IResult> GetOrdersDashboardAsync([FromServices] IDashboardService dashboardService, CancellationToken cancellationToken) private async Task<IResult> GetOrdersDashboardAsync([FromServices] IDashboardService dashboardService, CancellationToken cancellationToken)

View File

@ -9,25 +9,28 @@ public class DiscountController : ICarterModule
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser()); .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser());
group.MapGet("", GetAllAsync) group.MapGet("", GetAllAsync)
.WithDisplayName("GetAllDiscounts") .WithDisplayName("Get Discounts")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageDiscounts, ApplicationPermission.ViewDiscounts)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageDiscounts, ApplicationPermission.ViewDiscounts))
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapGet("{id}", GetAsync) group.MapGet("{id}", GetAsync)
.WithDisplayName("GetDiscount") .WithDisplayName("Get Discount")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageDiscounts, ApplicationPermission.ViewDiscounts)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageDiscounts, ApplicationPermission.ViewDiscounts))
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapPost("", Post) group.MapPost("", Post)
.HasApiVersion(1.0) .HasApiVersion(1.0)
.WithDisplayName("Create Discount")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageDiscounts)); .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageDiscounts));
group.MapPut("", Put) group.MapPut("", Put)
.HasApiVersion(1.0) .HasApiVersion(1.0)
.WithDisplayName("Update Discount")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageDiscounts)); .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageDiscounts));
group.MapDelete("{id}", Delete) group.MapDelete("{id}", Delete)
.HasApiVersion(1.0) .HasApiVersion(1.0)
.WithDisplayName("Delete Discount")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageDiscounts)); .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageDiscounts));
} }

View File

@ -11,7 +11,7 @@ public class DistrictController : ICarterModule
.WithDisplayName("Get Cities") .WithDisplayName("Get Cities")
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapGet("province", GetProvincesAsync) group.MapGet("province", GetProvincesAsync)
.WithDisplayName("Get Cities") .WithDisplayName("Get Provinces")
.HasApiVersion(1.0); .HasApiVersion(1.0);
} }

View File

@ -0,0 +1,56 @@
namespace Netina.Api.Controllers;
public class FaqController : ICarterModule
{
public void AddRoutes(IEndpointRouteBuilder app)
{
var group = app.NewVersionedApi("Faq")
.MapGroup("api/faq");
group.MapGet("/slug", GetFaqBySlugAsync)
.WithDisplayName("Get Faq By Slug")
.WithDescription("Get faq by slug , you have to send page slug")
.HasApiVersion(1.0);
group.MapGet("", GetFaqsAsync)
.WithDisplayName("Get Faqs")
.WithDescription("Get All Faqs")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer")
.RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageFaq))
.HasApiVersion(1.0);
group.MapPost("", CreateFaqAsync)
.WithDisplayName("Create Faq")
.WithDescription("Create Faq , you can create new faq or create update your faq ")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer")
.RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageFaq))
.HasApiVersion(1.0);
group.MapPut("", UpdateFaqAsync)
.WithDisplayName("Update Faq")
.WithDescription("Update Faq , you can create new faq or create update your faq ")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer")
.RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageFaq))
.HasApiVersion(1.0);
group.MapDelete("{id}", DeleteFaqAsync)
.WithDisplayName("Delete Faq")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageFaq))
.HasApiVersion(1.0);
}
private async Task<IResult> DeleteFaqAsync([FromRoute]Guid id,[FromServices] IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new DeleteFaqCommand(Id:id), cancellationToken));
private async Task<IResult> GetFaqsAsync([FromQuery]int page, [FromQuery] int? count ,[FromServices] IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new GetFaqsQuery(Count: count ?? 0 , Page:page), cancellationToken));
private async Task<IResult> CreateFaqAsync([FromBody] CreateFaqCommand request,[FromServices]IMediator mediator , CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(request, cancellationToken));
private async Task<IResult> UpdateFaqAsync([FromBody] UpdateFaqCommand request, [FromServices] IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(request, cancellationToken));
private async Task<IResult> GetFaqBySlugAsync([FromQuery] string slug, [FromServices] IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new GetFaqQuery(null, slug), cancellationToken));
}

View File

@ -1,4 +1,5 @@
using Netina.Domain.Enums; using Netina.Domain.Dtos.ResponseDtos;
using Netina.Domain.Enums;
namespace Netina.Api.Controllers; namespace Netina.Api.Controllers;
@ -10,14 +11,57 @@ public class FileController : ICarterModule
.MapGroup("api/file"); .MapGroup("api/file");
group.MapGet("", GetFilesAsync) group.MapGet("", GetFilesAsync)
.WithDisplayName("GetFilesAsync") .WithDisplayName("Get Files")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageFiles, ApplicationPermission.ViewFiles)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageFiles, ApplicationPermission.ViewFiles))
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapPost("", UploadFileAsync) group.MapPost("", UploadFileAsync)
.WithDisplayName("UploadFileAsync") .WithDisplayName("Upload File")
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapPost("/ckeditor", UploadCkEditorFileAsync)
.WithDisplayName("Upload CkEditor File")
.AllowAnonymous()
.DisableAntiforgery()
.HasApiVersion(1.0);
}
public async Task<IResult> UploadCkEditorFileAsync(IFormFile upload, [FromServices] IHttpContextAccessor httpContextAccessor, [FromServices] IStorageService storageService, IUploadFileService uploadFileService, CancellationToken cancellationToken)
{
try
{
if (httpContextAccessor.HttpContext?.Request?.Headers is { } dictionary && dictionary.TryGetValue("Authorization", out StringValues value))
{
if (value.ToString() != "xuwp4KzU1/YBoevpzgH0cz8+zLKQ+EOaYXeo4JtRxmVIuN7Hqxz97oQ398tNX68+")
throw new Exception("ارسال فایل از طرف شما معتبر نمی باشد");
using var stream = new MemoryStream();
await upload.CopyToAsync(stream, cancellationToken);
var uploadRequest = new FileUploadRequest
{
FileName = upload.FileName,
ContentType = upload.ContentType,
FileUploadType = FileUploadType.Image,
StringBaseFile = Convert.ToBase64String(stream.ToArray())
};
var fileUrl = await uploadFileService.UploadImageAsync(uploadRequest);
return TypedResults.Ok(new CkEditorFileUploadResponseDto { url = fileUrl.FileUrl });
}
throw new Exception("ارسال فایل از طرف شما معتبر نمی باشد");
}
catch (Exception e)
{
var errorMessage = new
{
message = e.Message
};
var errorResponse = new
{
error = errorMessage
};
return TypedResults.BadRequest(errorResponse);
}
} }
public async Task<IResult> GetFilesAsync([FromQuery]StorageFileType? fileType,[FromServices] IStorageService storageService, CancellationToken cancellationToken) public async Task<IResult> GetFilesAsync([FromQuery]StorageFileType? fileType,[FromServices] IStorageService storageService, CancellationToken cancellationToken)

View File

@ -9,13 +9,13 @@ public class HealthController : ICarterModule
var group = app.NewVersionedApi("Health") var group = app.NewVersionedApi("Health")
.MapGroup("health"); .MapGroup("health");
group.MapGet("", GetHealth) group.MapGet("", GetHealth)
.WithDisplayName("GetHealth") .WithDisplayName("Get Health")
.HasApiVersion(1.0); .HasApiVersion(1.0);
} }
public async Task<IResult> GetHealth([FromServices]ISiteMapService siteMapService) public async Task<IResult> GetHealth([FromServices]ISiteMapService siteMapService)
{ {
//await siteMapService.CreateSiteMapAsync(); await siteMapService.CreateSiteMapAsync();
var version = typeof(Program)?.Assembly.GetName()?.Version?.ToString(); var version = typeof(Program)?.Assembly.GetName()?.Version?.ToString();
var check = new HealthCheck var check = new HealthCheck
{ {

View File

@ -11,20 +11,20 @@ public class MarketerController : ICarterModule
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser()); .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser());
group.MapGet("", GetMarketersAsync) group.MapGet("", GetMarketersAsync)
.WithDisplayName("GetAllMarketers") .WithDisplayName("Get Marketers")
.RequireAuthorization(builder=>builder.RequireClaim(CustomClaimType.Permission,ApplicationPermission.ManageUsers , ApplicationPermission.ViewUsers)) .RequireAuthorization(builder=>builder.RequireClaim(CustomClaimType.Permission,ApplicationPermission.ManageUsers , ApplicationPermission.ViewUsers))
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapGet("profile", GetMarketerProfileAsync) group.MapGet("profile", GetMarketerProfileAsync)
.WithDisplayName("GetAllMarketers") .WithDisplayName("Get Marketer Profile")
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapPost("signup", SignUpMarketerAsync) group.MapPost("signup", SignUpMarketerAsync)
.WithDisplayName("SignUpMarketer") .WithDisplayName("SignUp Marketer")
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapGet("signup/contract", GetSignUpMarketerContractAsync) group.MapGet("signup/contract", GetSignUpMarketerContractAsync)
.WithDisplayName("SignUpMarketerContract") .WithDisplayName("Get Marketer Contract")
.HasApiVersion(1.0); .HasApiVersion(1.0);
} }

View File

@ -7,7 +7,7 @@ public class NewsletterMemberController : ICarterModule
var group = app.NewVersionedApi("Newsletter Members").MapGroup("api/newsletter/member"); var group = app.NewVersionedApi("Newsletter Members").MapGroup("api/newsletter/member");
group.MapGet("", GetAllMembersAsync) group.MapGet("", GetAllMembersAsync)
.WithDisplayName("Get All Members") .WithDisplayName("Get Members")
.HasApiVersion(1.0) .HasApiVersion(1.0)
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewNewsletterMembers)); .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewNewsletterMembers));

View File

@ -11,38 +11,38 @@ public class OrderBagController : ICarterModule
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.CreateOrder)); .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.CreateOrder));
group.MapGet("", GetUserCurrentOrderBagAsync) group.MapGet("", GetUserCurrentOrderBagAsync)
.WithDisplayName("GetUserCurrentOrderBag") .WithDisplayName("Get User Current OrderBag")
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapPost("check", CheckOrderBagAsync) group.MapPost("check", CheckOrderBagAsync)
.WithDisplayName("CheckOrderBag") .WithDisplayName("Check OrderBag")
.AllowAnonymous() .AllowAnonymous()
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapPost("add", AddProductToBagAsync) group.MapPost("add", AddProductToBagAsync)
.WithDisplayName("AddProductToBag") .WithDisplayName("Add Product To OrderBag")
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapDelete("remove", RemoveFromOrderBagAsync) group.MapDelete("remove", RemoveFromOrderBagAsync)
.WithDisplayName("RemoveFromOrderBag") .WithDisplayName("Remove From OrderBag")
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapPost("submit", SubmitOrderBagAsync) group.MapPost("submit", SubmitOrderBagAsync)
.WithDisplayName("SubmitOrderBag") .WithDisplayName("Submit OrderBag")
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapPost("discount/{orderId}", AddDiscountToOrderBagAsync) group.MapPost("discount/{orderId}", DiscountActionOrderBagAsync)
.WithDisplayName("AddDiscountToOrderBag") .WithDisplayName("Add Discount To OrderBag")
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapPost("shipping/{orderId}", AddShippingToOrderBagAsync) group.MapPost("shipping/{orderId}", AddShippingToOrderBagAsync)
.WithDisplayName("AddShippingToOrderBag") .WithDisplayName("Add Shipping To OrderBag")
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapPost("payment/{orderId}", SubmitOrderPaymentAsync) group.MapPost("payment/{orderId}", SubmitOrderPaymentAsync)
.WithDisplayName("SubmitOrderPayment") .WithDisplayName("Submit Order Payment")
.HasApiVersion(1.0); .HasApiVersion(1.0);
} }
@ -62,8 +62,8 @@ public class OrderBagController : ICarterModule
public async Task<IResult> RemoveFromOrderBagAsync([FromBody] List<OrderBagRequestDto> requestDtos, IMediator mediator, CancellationToken cancellationToken) public async Task<IResult> RemoveFromOrderBagAsync([FromBody] List<OrderBagRequestDto> requestDtos, IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new RemoveFromOrderBagCommand(requestDtos), cancellationToken)); => TypedResults.Ok(await mediator.Send(new RemoveFromOrderBagCommand(requestDtos), cancellationToken));
public async Task<IResult> AddDiscountToOrderBagAsync(Guid orderId, [FromQuery] string discountCode, IMediator mediator, CancellationToken cancellationToken) public async Task<IResult> DiscountActionOrderBagAsync(Guid orderId, [FromQuery] string? discountCode, IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new SubmitDiscountCommand(orderId, discountCode), cancellationToken)); => TypedResults.Ok(await mediator.Send(new SubmitDiscountActionCommand(orderId, discountCode), cancellationToken));
public async Task<IResult> AddShippingToOrderBagAsync(Guid orderId, [FromBody] SubmitOrderDeliveryCommand request, IMediator mediator, CancellationToken cancellationToken) public async Task<IResult> AddShippingToOrderBagAsync(Guid orderId, [FromBody] SubmitOrderDeliveryCommand request, IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(request with { OrderId = orderId }, cancellationToken)); => TypedResults.Ok(await mediator.Send(request with { OrderId = orderId }, cancellationToken));

View File

@ -10,27 +10,35 @@ public class OrderController : ICarterModule
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser()); .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser());
group.MapGet("", GetAllAsync) group.MapGet("", GetAllAsync)
.WithDisplayName("GetAllOrders") .WithDisplayName("Get Orders")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewAllOrders , ApplicationPermission.ManageOrders)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewAllOrders , ApplicationPermission.ManageOrders))
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapGet("{id}", GetAsync) group.MapGet("{id}", GetAsync)
.WithDisplayName("GetOneOrder") .WithDisplayName("Get Order")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewAllOrders, ApplicationPermission.ManageOrders)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission,
ApplicationPermission.ViewAllOrders,
ApplicationPermission.ManageOrders,
ApplicationPermission.ViewMineOrders))
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapPost("{id}/confirm", ConfirmOrderStepAsync) group.MapPost("{id}/confirm", ConfirmOrderStepAsync)
.WithDisplayName("ConfirmOrderStep") .WithDisplayName("Confirm OrderStep")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageOrders)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageOrders))
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapPost("{id}/cancel", CancelOrderStepAsync)
.WithDisplayName("Cancel Order")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageOrders))
.HasApiVersion(1.0);
group.MapDelete("{id}", DeleteAsync) group.MapDelete("{id}", DeleteAsync)
.WithDisplayName("DeleteOneOrder") .WithDisplayName("Delete Order")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageOrders)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageOrders))
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapGet("{id}/invoice", GetOrderInvoiceAsync) group.MapGet("{id}/invoice", GetOrderInvoiceAsync)
.WithDisplayName("GetOrderInvoice") .WithDisplayName("Get Order Invoice")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageOrders)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageOrders))
.AllowAnonymous() .AllowAnonymous()
.HasApiVersion(1.0); .HasApiVersion(1.0);
@ -40,8 +48,18 @@ public class OrderController : ICarterModule
private async Task<IResult> ConfirmOrderStepAsync(Guid id, [FromQuery] OrderStatus nextOrderStatus, [FromQuery]string? trackingCode, [FromServices] IMediator mediator, CancellationToken cancellationToken) private async Task<IResult> ConfirmOrderStepAsync(Guid id, [FromQuery] OrderStatus nextOrderStatus, [FromQuery]string? trackingCode, [FromServices] IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new ConfirmOrderStepCommand(id, nextOrderStatus,TrackingCode:trackingCode), cancellationToken)); => TypedResults.Ok(await mediator.Send(new ConfirmOrderStepCommand(id, nextOrderStatus,TrackingCode:trackingCode), cancellationToken));
public async Task<IResult> GetAllAsync(IMediator mediator, [FromQuery]string? factorCode, [FromQuery]long? selectedDate, [FromQuery] OrderStatus? orderStatus, [FromQuery] OrderQueryDateFilter? dateFilter, [FromQuery] int page = 0, CancellationToken cancellationToken = default) private async Task<IResult> CancelOrderStepAsync(Guid id, [FromServices] IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new GetOrdersQuery(Page:page, FactorCode:factorCode , SelectedDate: selectedDate, OrderStatus:orderStatus, DateFilter:dateFilter), cancellationToken)); => TypedResults.Ok(await mediator.Send(new CancelOrderStepCommand(id), cancellationToken));
public async Task<IResult> GetAllAsync(IMediator mediator,
[FromQuery]string? factorCode,
[FromQuery]long? selectedDate,
[FromQuery]OrderStatus? orderStatus,
[FromQuery]OrderQueryDateFilter? dateFilter,
[FromQuery]bool? orderBags,
[FromQuery]int page = 0,
CancellationToken cancellationToken = default)
=> TypedResults.Ok(await mediator.Send(new GetOrdersQuery(Page:page, FactorCode:factorCode ,OrderBags:orderBags??false , SelectedDate: selectedDate, OrderStatus:orderStatus, DateFilter:dateFilter), cancellationToken));
public async Task<IResult> GetAsync(IMediator mediator, Guid id, CancellationToken cancellationToken = default) public async Task<IResult> GetAsync(IMediator mediator, Guid id, CancellationToken cancellationToken = default)
{ {

View File

@ -12,6 +12,13 @@ public class PageController : ICarterModule
.HasApiVersion(1.0) .HasApiVersion(1.0)
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewPages, ApplicationPermission.ManagePages)); .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewPages, ApplicationPermission.ManagePages));
group.MapGet("redirect/check", CheckRedirectedOldLinkAsync)
.WithDisplayName("Check Redirect OldLink")
.HasApiVersion(1.0);
group.MapGet("deleted/check", CheckDeletedLinkAsync)
.WithDisplayName("Check Deleted Link")
.HasApiVersion(1.0);
group.MapGet("{id}", GetPageByIdAsync) group.MapGet("{id}", GetPageByIdAsync)
.WithDisplayName("Get Page") .WithDisplayName("Get Page")
@ -31,6 +38,10 @@ public class PageController : ICarterModule
.HasApiVersion(1.0) .HasApiVersion(1.0)
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManagePages)); .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManagePages));
group.MapPut("", UpdatePageAsync)
.WithDisplayName("Update Page")
.HasApiVersion(1.0)
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManagePages));
group.MapDelete("{id}", DeletePageByIdAsync) group.MapDelete("{id}", DeletePageByIdAsync)
.WithDisplayName("Delete Page") .WithDisplayName("Delete Page")
@ -39,31 +50,35 @@ public class PageController : ICarterModule
} }
private async Task<IResult> CheckDeletedLinkAsync([FromQuery] string link, [FromServices] IPageService pageService, CancellationToken cancellationToken)
=> TypedResults.Ok(await pageService.CheckDeletedAsync(link, cancellationToken));
private async Task<IResult> CheckRedirectedOldLinkAsync([FromQuery] string oldUrl, [FromServices] IPageService pageService, CancellationToken cancellationToken)
=> TypedResults.Content(await pageService.CheckRedirectAsync(oldUrl, cancellationToken));
private async Task<IResult> DeletePageByIdAsync([FromRoute]Guid id,[FromServices]IPageService pageService,CancellationToken cancellationToken) private async Task<IResult> DeletePageByIdAsync([FromRoute]Guid id,[FromServices]IPageService pageService,CancellationToken cancellationToken)
=> TypedResults.Ok(await pageService.DeletePageAsync(id, cancellationToken)); => TypedResults.Ok(await pageService.DeletePageAsync(id, cancellationToken));
public async Task<IResult> GetPagesAsync([FromServices] IPageService pageService, CancellationToken cancellationToken) public async Task<IResult> GetPagesAsync([FromServices] IPageService pageService, CancellationToken cancellationToken)
{ => TypedResults.Ok(await pageService.GetPagesAsync(cancellationToken));
return TypedResults.Ok(await pageService.GetPagesAsync(cancellationToken));
}
public async Task<IResult> GetPageByIdAsync(Guid id ,[FromServices] IPageService pageService, CancellationToken cancellationToken) public async Task<IResult> GetPageByIdAsync(Guid id ,[FromServices] IPageService pageService, CancellationToken cancellationToken)
{ => TypedResults.Ok(await pageService.GetPageAsync(id: id, cancellationToken: cancellationToken));
return TypedResults.Ok(await pageService.GetPageAsync(id: id,cancellationToken: cancellationToken));
}
public async Task<IResult> GetPageByTypeAsync(string type, [FromServices] IPageService pageService, CancellationToken cancellationToken) public async Task<IResult> GetPageByTypeAsync(string type, [FromServices] IPageService pageService, CancellationToken cancellationToken)
{ => TypedResults.Ok(await pageService.GetPageAsync(type: type, cancellationToken: cancellationToken));
return TypedResults.Ok(await pageService.GetPageAsync(type: type, cancellationToken: cancellationToken));
}
public async Task<IResult> GetPageAsync(string pageSlug, [FromServices] IPageService pageService, CancellationToken cancellationToken) public async Task<IResult> GetPageAsync(string pageSlug, [FromServices] IPageService pageService, CancellationToken cancellationToken)
{ => TypedResults.Ok(await pageService.GetPageAsync(pageSlug: pageSlug, cancellationToken: cancellationToken));
return TypedResults.Ok(await pageService.GetPageAsync(pageSlug: pageSlug,cancellationToken: cancellationToken));
}
public async Task<IResult> PostPageAsync([FromBody] PageActionRequestDto page, [FromServices] IPageService pageService, CancellationToken cancellationToken) public async Task<IResult> PostPageAsync([FromBody] PageActionRequestDto page, [FromServices] IPageService pageService, CancellationToken cancellationToken)
{ {
await pageService.CreatePageAsync(page, cancellationToken); await pageService.CreatePageAsync(page, cancellationToken);
return TypedResults.Ok(); return TypedResults.Ok();
} }
public async Task<IResult> UpdatePageAsync([FromBody] PageActionRequestDto page, [FromServices] IPageService pageService, CancellationToken cancellationToken)
{
await pageService.UpdatePageAsync(page, cancellationToken);
return TypedResults.Ok();
}
} }

View File

@ -12,7 +12,7 @@ public class PaymentController : ICarterModule
.MapGroup($"api/accounting/pay"); .MapGroup($"api/accounting/pay");
group.MapGet("", GetAllAsync) group.MapGet("", GetAllAsync)
.WithDisplayName("GetPayments") .WithDisplayName("Get Payments")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewPayments)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewPayments))
.HasApiVersion(1.0); .HasApiVersion(1.0);
@ -22,6 +22,7 @@ public class PaymentController : ICarterModule
// .HasApiVersion(1.0); // .HasApiVersion(1.0);
group.MapGet("verify", VerifyPaymentAsync) group.MapGet("verify", VerifyPaymentAsync)
.WithDisplayName("Verify Payment")
.HasApiVersion(1.0); .HasApiVersion(1.0);
} }

View File

@ -9,22 +9,25 @@ public class ProductCategoryController : ICarterModule
.MapGroup($"api/product/category"); .MapGroup($"api/product/category");
group.MapGet("", GetAllAsync) group.MapGet("", GetAllAsync)
.WithDisplayName("GetAllCategories") .WithDisplayName("Get ProductCategories")
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapGet("{id}", GetAsync) group.MapGet("{id}", GetAsync)
.WithDisplayName("GetCategory") .WithDisplayName("Get ProductCategory")
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapPost("", Post) group.MapPost("", Post)
.WithDisplayName("Create ProductCategory")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission,ApplicationPermission.ManageProducts)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission,ApplicationPermission.ManageProducts))
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapPut("", Put) group.MapPut("", Put)
.WithDisplayName("Update ProductCategory")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageProducts)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageProducts))
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapDelete("{id}", Delete) group.MapDelete("{id}", Delete)
.WithDisplayName("Delete ProductCategory")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageProducts)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageProducts))
.HasApiVersion(1.0); .HasApiVersion(1.0);
} }

View File

@ -11,37 +11,66 @@ public class ProductController : ICarterModule
.MapGroup($"api/product"); .MapGroup($"api/product");
group.MapGet("", GetAllAsync) group.MapGet("", GetAllAsync)
.WithDisplayName("GetAllProducts") .WithDisplayName("Get Products")
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapGet("{id}", GetAsync) group.MapGet("{id}", GetAsync)
.WithDisplayName("GetProducts") .WithDisplayName("Get Product")
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapPost("", Post) group.MapPost("", Post)
.WithDisplayName("Create Product")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageProducts)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageProducts))
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapPut("", Put) group.MapPut("", Put)
.WithDisplayName("Update Product")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageProducts)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageProducts))
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapPut("{productId}", ChangeDisplayedAsync) group.MapGet("{productId}/sub", GetSubProductsAsync)
.WithDisplayName("Get Sub Products")
.HasApiVersion(1.0);
group.MapPut("{productId}/displayed", ChangeDisplayedAsync)
.WithDisplayName("Change Product Display")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageProducts)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageProducts))
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapPut("{productId}/cost", ChangeCostAsync)
.WithDisplayName("Change Product Cost")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageProducts))
.HasApiVersion(1.0);
group.MapGet("{productId}/comment",GetProductCommentsAsync)
.WithDisplayName("Get Product Comments")
.HasApiVersion(1.0);
group.MapDelete("{id}", Delete) group.MapDelete("{id}", Delete)
.WithDisplayName("Delete Product")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageProducts)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageProducts))
.HasApiVersion(1.0); .HasApiVersion(1.0);
} }
private async Task<IResult> GetProductCommentsAsync([FromQuery] int page, [FromQuery]int count, [FromRoute] Guid productId, IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new GetCommentsQuery(page, count, productId), cancellationToken));
// GET:Get All Entity // GET:Get All Entity
public async Task<IResult> GetAllAsync([FromQuery] int page, [FromQuery]string? productName, [FromQuery] QuerySortBy? sortBy, [FromQuery] Guid? categoryId, [FromQuery] bool? specialOffer, [FromQuery] Guid[]? brandIds , [FromQuery]double? minPrice , [FromQuery] double? maxPrice, [FromQuery]bool? isActive, IMediator mediator, CancellationToken cancellationToken) public async Task<IResult> GetAllAsync([FromQuery] int page,
=> TypedResults.Ok(await mediator.Send(new GetProductsQuery(Page: page, SpecialOffer: specialOffer, SortBy: sortBy ?? 0 ,ProductName: productName, CategoryId: categoryId ?? default , BrandIds: brandIds , MinPrice: minPrice ?? -1 , MaxPrice:maxPrice ?? 0,IsActive:isActive),cancellationToken)); [FromQuery] string? productName,
[FromQuery] QuerySortBy? sortBy,
[FromQuery] Guid? categoryId,
[FromQuery] bool? specialOffer,
[FromQuery] Guid[]? brandIds,
[FromQuery] double? minPrice,
[FromQuery] double? maxPrice,
[FromQuery] bool? isActive,
IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new GetProductsQuery(Page: page, SpecialOffer: specialOffer, SortBy: sortBy ?? 0, ProductName: productName, CategoryId: categoryId ?? default, BrandIds: brandIds, MinPrice: minPrice ?? -1, MaxPrice: maxPrice ?? 0, IsActive: isActive), cancellationToken));
// GET:Get An Entity By Id // GET:Get An Entity By Id
public async Task<IResult> GetAsync(Guid id, IMediator mediator,CancellationToken cancellationToken) public async Task<IResult> GetAsync(Guid id, IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new GetProductQuery(id),cancellationToken)); => TypedResults.Ok(await mediator.Send(new GetProductQuery(id), cancellationToken));
// POST:Create Entity // POST:Create Entity
public async Task<IResult> Post([FromBody] CreateProductCommand request, IMediator mediator, public async Task<IResult> Post([FromBody] CreateProductCommand request, IMediator mediator,
@ -53,9 +82,17 @@ public class ProductController : ICarterModule
CancellationToken cancellationToken) CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(request, cancellationToken)); => TypedResults.Ok(await mediator.Send(request, cancellationToken));
public async Task<IResult> ChangeDisplayedAsync(Guid productId, [FromQuery]bool beDisplayed, [FromServices] IMediator mediator, CancellationToken cancellationToken) // PUT:Update Entity
public async Task<IResult> GetSubProductsAsync(Guid productId, IMediator mediator,
CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new GetSubProductsQuery(productId), cancellationToken));
public async Task<IResult> ChangeDisplayedAsync(Guid productId, [FromQuery] bool beDisplayed, [FromServices] IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new ChangeProductDisplayedCommand(productId, beDisplayed), cancellationToken)); => TypedResults.Ok(await mediator.Send(new ChangeProductDisplayedCommand(productId, beDisplayed), cancellationToken));
public async Task<IResult> ChangeCostAsync(Guid productId, [FromQuery] double cost, [FromServices] IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new ChangeProductCostCommand(productId, cost), cancellationToken));
// DELETE:Delete Entity // DELETE:Delete Entity
public async Task<IResult> Delete(Guid id, IMediator mediator, CancellationToken cancellationToken) public async Task<IResult> Delete(Guid id, IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new DeleteProductCommand(id), cancellationToken)); => TypedResults.Ok(await mediator.Send(new DeleteProductCommand(id), cancellationToken));

View File

@ -11,29 +11,32 @@ public class RoleController : ICarterModule
.MapGroup($"api/user/role"); .MapGroup($"api/user/role");
group.MapGet("", GetAllAsync) group.MapGet("", GetAllAsync)
.WithDisplayName("GetAllRoles") .WithDisplayName("Get Roles")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewRoles, ApplicationPermission.ManageRoles)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewRoles, ApplicationPermission.ManageRoles))
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapGet("permission", GetAllPermissions) group.MapGet("permission", GetAllPermissions)
.WithDisplayName("GetAllPermissions") .WithDisplayName("Get Permissions")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewRoles, ApplicationPermission.ManageRoles)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewRoles, ApplicationPermission.ManageRoles))
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapGet("{id}", GetAsync) group.MapGet("{id}", GetAsync)
.WithDisplayName("GetRole") .WithDisplayName("Get Role")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewRoles, ApplicationPermission.ManageRoles)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewRoles, ApplicationPermission.ManageRoles))
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapPost("", Post) group.MapPost("", Post)
.WithDisplayName("Create Role")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageRoles)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageRoles))
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapPut("", Put) group.MapPut("", Put)
.WithDisplayName("Update Role")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageRoles)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageRoles))
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapDelete("{id}", Delete) group.MapDelete("{id}", Delete)
.WithDisplayName("Delete Role")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageRoles)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageRoles))
.HasApiVersion(1.0); .HasApiVersion(1.0);
} }

View File

@ -9,11 +9,11 @@ public class ScraperController : ICarterModule
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission,ApplicationPermission.ManageScraper)); .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission,ApplicationPermission.ManageScraper));
group.MapGet("digi", GetDigiProductsAsync) group.MapGet("digi", GetDigiProductsAsync)
.WithDisplayName("GetDigiProducts") .WithDisplayName("Get DigiProducts")
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapPost("digi/{productId}", AddProductToShopAsync) group.MapPost("digi/{productId}", AddProductToShopAsync)
.WithDisplayName("AddProductToShop") .WithDisplayName("Add DigiProduct To Shop")
.HasApiVersion(1.0); .HasApiVersion(1.0);
} }

View File

@ -10,19 +10,19 @@ public class SearchController : ICarterModule
group.MapGet("/thumb", SearchThumbAsync) group.MapGet("/thumb", SearchThumbAsync)
.WithDisplayName("Thumb Search Async") .WithDisplayName("Thumb Search")
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapGet("zarehbin", ZarehbinAsync) group.MapGet("zarehbin", ZarehbinAsync)
.WithDisplayName("Search Async") .WithDisplayName("Get Zarehbin Product")
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapGet("torob", TorobAsync) group.MapGet("torob", TorobAsync)
.WithDisplayName("Get Torob Product Async") .WithDisplayName("Get Torob Product")
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapGet("emalls", EmallsAsync) group.MapGet("emalls", EmallsAsync)
.WithDisplayName("Get Emalls Product Async") .WithDisplayName("Get Emalls Product")
.HasApiVersion(1.0); .HasApiVersion(1.0);
} }

View File

@ -2,17 +2,11 @@
using Netina.Domain.Entities.Blogs; using Netina.Domain.Entities.Blogs;
namespace Netina.Api.Controllers; namespace Netina.Api.Controllers;
public class SeedController : ICarterModule public class SeedController(IWebHostEnvironment environment) : ICarterModule
{ {
private readonly IWebHostEnvironment _environment;
public SeedController(IWebHostEnvironment environment)
{
_environment = environment;
}
public void AddRoutes(IEndpointRouteBuilder app) public void AddRoutes(IEndpointRouteBuilder app)
{ {
if (_environment.IsDevelopment()) if (environment.IsDevelopment())
{ {
var group = app.NewVersionedApi("Seed") var group = app.NewVersionedApi("Seed")
.MapGroup("api/seed"); .MapGroup("api/seed");
@ -78,13 +72,14 @@ public class SeedController : ICarterModule
var baseCat = await mediator.Send(new CreateProductCategoryCommand("دسته بندی نشده", "محصولات دسته بندی نشده", var baseCat = await mediator.Send(new CreateProductCategoryCommand("دسته بندی نشده", "محصولات دسته بندی نشده",
true, true,
default, default,
new List<StorageFileSDto>()),cancellationToken); new List<StorageFileSDto>(),
new Dictionary<string, string>(),
new Dictionary<string, string>()),cancellationToken);
categories.Add(0,baseCat); categories.Add(0,baseCat);
foreach (var requestDto in request) foreach (var requestDto in request)
{ {
var lDto = await mediator.Send(new CreateProductCategoryCommand(requestDto.Name,requestDto.Description,true,default, var lDto = await mediator.Send(new CreateProductCategoryCommand(requestDto.Name,requestDto.Description,true,default,
new List<StorageFileSDto>(),new Dictionary<string, string>(),new Dictionary<string, string>()), cancellationToken);
new List<StorageFileSDto>()), cancellationToken);
categories.Add(requestDto.BaseCategoryId,lDto); categories.Add(requestDto.BaseCategoryId,lDto);
} }
@ -97,13 +92,18 @@ public class SeedController : ICarterModule
if (key != "kKAYskyG8xPxKnJrHkuYxub4Ao2bnz7AOmNtwDT0RaqzaG7ZvbvaP29tCrC8wJ823RczJFXOIQT2bDOec4F38A==") if (key != "kKAYskyG8xPxKnJrHkuYxub4Ao2bnz7AOmNtwDT0RaqzaG7ZvbvaP29tCrC8wJ823RczJFXOIQT2bDOec4F38A==")
throw new AppException("Key is not valid", ApiResultStatusCode.UnAuthorized); throw new AppException("Key is not valid", ApiResultStatusCode.UnAuthorized);
Dictionary<int, Guid> brands = new Dictionary<int, Guid>(); Dictionary<int, Guid> brands = new Dictionary<int, Guid>();
var baseBrand = await mediator.Send(new CreateBrandCommand("بدون برند","NoBrand", "محصولات بدون برند", false,string.Empty, var baseBrand = await mediator.Send(new CreateBrandCommand("بدون برند","NoBrand",
new List<StorageFileSDto>()), cancellationToken); "محصولات بدون برند",
false,
string.Empty,
new List<StorageFileSDto>(),
new Dictionary<string, string>(),
new Dictionary<string, string>()), cancellationToken);
brands.Add(0, baseBrand); brands.Add(0, baseBrand);
foreach (var requestDto in request) foreach (var requestDto in request)
{ {
var sDto = await mediator.Send(new CreateBrandCommand(requestDto.Name,string.Empty, requestDto.Description, false, var sDto = await mediator.Send(new CreateBrandCommand(requestDto.Name,string.Empty, requestDto.Description, false,
string.Empty, new List<StorageFileSDto>()), cancellationToken); string.Empty, new List<StorageFileSDto>(),new Dictionary<string, string>(),new Dictionary<string, string>()), cancellationToken);
brands.Add(requestDto.BaseBrandId,sDto); brands.Add(requestDto.BaseBrandId,sDto);
} }
@ -126,7 +126,7 @@ public class SeedController : ICarterModule
seedBlogRequestDto.CategoryId = noCategory.Id; seedBlogRequestDto.CategoryId = noCategory.Id;
} }
var ent = Blog.Create(seedBlogRequestDto.Title, seedBlogRequestDto.Slug, seedBlogRequestDto.Content, seedBlogRequestDto.Tags, seedBlogRequestDto.ReadingTime, var ent = Blog.Create(seedBlogRequestDto.Title, seedBlogRequestDto.Slug, seedBlogRequestDto.Content, seedBlogRequestDto.Tags, seedBlogRequestDto.ReadingTime,
seedBlogRequestDto.Summery, seedBlogRequestDto.IsSuggested, seedBlogRequestDto.CategoryId); seedBlogRequestDto.Summery, seedBlogRequestDto.IsSuggested, seedBlogRequestDto.CategoryId,default);
foreach (var storageFileSDto in seedBlogRequestDto.Files) foreach (var storageFileSDto in seedBlogRequestDto.Files)
{ {

View File

@ -10,12 +10,12 @@ public class SettingController : ICarterModule
.MapGroup("api/setting"); .MapGroup("api/setting");
group.MapGet("{settingName}", GetSettingAsync) group.MapGet("{settingName}", GetSettingAsync)
.WithDisplayName("GetSetting") .WithDisplayName("Get Setting")
.RequireAuthorization(builder=>builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewSettings,ApplicationPermission.ManageSettings)) .RequireAuthorization(builder=>builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewSettings,ApplicationPermission.ManageSettings))
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapPost("{settingName}", PostSettingAsync) group.MapPost("{settingName}", PostSettingAsync)
.WithDisplayName("PostSettingAsync") .WithDisplayName("Create Setting")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageSettings)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageSettings))
.HasApiVersion(1.0); .HasApiVersion(1.0);
} }

View File

@ -9,23 +9,26 @@ public class ShippingController : ICarterModule
.MapGroup($"api/warehouse/shipping"); .MapGroup($"api/warehouse/shipping");
group.MapGet("", GetAllAsync) group.MapGet("", GetAllAsync)
.WithDisplayName("GetAllShipping") .WithDisplayName("Get Shipping")
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapGet("{id}", GetAsync) group.MapGet("{id}", GetAsync)
.WithDisplayName("GetShipping") .WithDisplayName("Get Shipping")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewShipping, ApplicationPermission.ManageShipping)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewShipping, ApplicationPermission.ManageShipping))
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapPost("", Post) group.MapPost("", Post)
.WithDisplayName("Create Shipping")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageShipping)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageShipping))
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapPut("", Put) group.MapPut("", Put)
.WithDisplayName("Update Shipping")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageShipping)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageShipping))
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapDelete("{id}", Delete) group.MapDelete("{id}", Delete)
.WithDisplayName("Delete Shipping")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageShipping)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageShipping))
.HasApiVersion(1.0); .HasApiVersion(1.0);
} }

View File

@ -0,0 +1,40 @@
namespace Netina.Api.Controllers;
public class SubProductController : ICarterModule
{
public virtual void AddRoutes(IEndpointRouteBuilder app)
{
var group = app.NewVersionedApi("SubProduct")
.MapGroup($"api/sub/product");
group.MapPost("", PostAsync)
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageBlogs))
.WithDisplayName("Create SubProduct")
.HasApiVersion(1.0);
group.MapPut("", PutAsync)
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageBlogs))
.WithDisplayName("Update SubProduct")
.HasApiVersion(1.0);
group.MapDelete("{id}", DeleteAsync)
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageBlogs))
.WithDisplayName("Delete SubProduct")
.HasApiVersion(1.0);
}
// POST:Create Entity
private async Task<IResult> PostAsync([FromBody] CreateSubProductCommand request, IMediator mediator,
CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(request, cancellationToken));
// PUT:Update Entity
private async Task<IResult> PutAsync([FromBody] UpdateSubProductCommand request, IMediator mediator,
CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(request, cancellationToken));
// DELETE:Delete Entity
private async Task<IResult> DeleteAsync(Guid id, IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new DeleteSubProductCommand(id), cancellationToken));
}

View File

@ -13,7 +13,7 @@ public class UserAddressController : ICarterModule
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapPost("", PostAddressesAsync) group.MapPost("", PostAddressesAsync)
.WithDisplayName("Post Addresses") .WithDisplayName("Create Addresses")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser()) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser())
.HasApiVersion(1.0); .HasApiVersion(1.0);

View File

@ -12,44 +12,47 @@ public class UserController : ICarterModule
.MapGroup($"api/user"); .MapGroup($"api/user");
group.MapGet("info", GetUserInfoAsync) group.MapGet("info", GetUserInfoAsync)
.WithDisplayName("GetUserInfo") .WithDisplayName("Get UserInfo")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser()) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser())
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapGet("", GetAllAsync) group.MapGet("", GetAllAsync)
.WithDisplayName("GetAllUsers") .WithDisplayName("Get Users")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewUsers, ApplicationPermission.ManageUsers)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewUsers, ApplicationPermission.ManageUsers))
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapGet("{id}", GetAsync) group.MapGet("{id}", GetAsync)
.WithDisplayName("GetUser") .WithDisplayName("Get User")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewUsers, ApplicationPermission.ManageUsers)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewUsers, ApplicationPermission.ManageUsers))
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapGet("/order", GetUserOrdersAsync) group.MapGet("/order", GetUserOrdersAsync)
.WithDisplayName("GetUserOrders") .WithDisplayName("Get UserOrders By JWT")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewMineOrders)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewMineOrders))
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapGet("{id}/order", GetUserOrdersByIdAsync) group.MapGet("{id}/order", GetUserOrdersByIdAsync)
.WithDisplayName("GetUserOrders") .WithDisplayName("Get UserOrders")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewAllOrders)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewAllOrders))
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapGet("/changelog", GetChangeLogAsync) group.MapGet("/changelog", GetChangeLogAsync)
.WithDisplayName("GetChangeLog") .WithDisplayName("Get ChangeLog")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageDashboard)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageDashboard))
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapPost("", Post) group.MapPost("", Post)
.WithDisplayName("Create User")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageUsers)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageUsers))
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapPut("", Put) group.MapPut("", Put)
.WithDisplayName("Update User")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageUsers)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageUsers))
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapDelete("{id}", Delete) group.MapDelete("{id}", Delete)
.WithDisplayName("Delete User")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageUsers)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageUsers))
.HasApiVersion(1.0); .HasApiVersion(1.0);
} }

View File

@ -1,6 +1,9 @@
namespace Netina.Api.Controllers; using Netina.Domain.Enums;
using Netina.Domain.MartenEntities.Settings;
public class WebSiteController:ICarterModule namespace Netina.Api.Controllers;
public class WebSiteController : ICarterModule
{ {
public void AddRoutes(IEndpointRouteBuilder app) public void AddRoutes(IEndpointRouteBuilder app)
{ {
@ -9,8 +12,38 @@ public class WebSiteController:ICarterModule
group.MapGet("/navbar", GetNavBarItemsAsync) group.MapGet("/navbar", GetNavBarItemsAsync)
.WithDisplayName("Get NavBar Items") .WithDisplayName("Get NavBar Items")
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapGet("/catelog", GetCatalogAsync)
.WithDisplayName("Get Catalog Items")
.HasApiVersion(1.0);
group.MapGet("/banner", GetBannerAsync)
.WithDisplayName("Get Banner Items")
.HasApiVersion(1.0);
} }
private async Task<IResult> GetNavBarItemsAsync([FromServices] IMediator mediator, CancellationToken cancellationToken) private async Task<IResult> GetNavBarItemsAsync([FromServices] IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new GetWebSiteNavBarCommand(),cancellationToken)); => TypedResults.Ok(await mediator.Send(new GetWebSiteNavBarCommand(),cancellationToken));
private async Task<IResult> GetCatalogAsync([FromServices] ISettingService settingService, CancellationToken cancellationToken)
{
var setting = await settingService.GetSettingAsync(nameof(PersonalizationSetting), cancellationToken);
if (setting is PersonalizationSetting personalizationSetting)
{
return TypedResults.Ok(personalizationSetting.Catalog);
}
throw new BaseApiException(ApiResultStatusCode.BadRequest, "Catalogs not found");
}
private async Task<IResult> GetBannerAsync([FromQuery]BannerSection? section,[FromServices] ISettingService settingService, CancellationToken cancellationToken)
{
var setting = await settingService.GetSettingAsync(nameof(PersonalizationSetting), cancellationToken);
if (setting is not PersonalizationSetting personalizationSetting)
throw new BaseApiException(ApiResultStatusCode.BadRequest, "Catalogs not found");
if (section != null)
return TypedResults.Ok(personalizationSetting.Banners.Where(b => b.Section == section));
return TypedResults.Ok(personalizationSetting.Banners);
}
} }

View File

@ -22,8 +22,6 @@ RUN dotnet publish "./Netina.Api.csproj" -c $BUILD_CONFIGURATION -o /app/publish
FROM base AS final FROM base AS final
RUN apt-get update
RUN apt-get install-y libgdiplus
WORKDIR /app WORKDIR /app
COPY --from=publish /app/publish . COPY --from=publish /app/publish .

View File

@ -6,53 +6,54 @@
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<InvariantGlobalization>true</InvariantGlobalization> <InvariantGlobalization>true</InvariantGlobalization>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS> <DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<AssemblyVersion>1.0.3.3</AssemblyVersion> <AssemblyVersion>1.14.22.42</AssemblyVersion>
<FileVersion>1.0.3.3</FileVersion> <FileVersion>1.14.22.42</FileVersion>
<LangVersion>latest</LangVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.4" /> <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.8" />
<PackageReference Include="Asp.Versioning.Http" Version="8.1.0" /> <PackageReference Include="Asp.Versioning.Http" Version="8.1.0" />
<PackageReference Include="Ben.BlockingDetector" Version="0.0.4" /> <PackageReference Include="Ben.BlockingDetector" Version="0.0.4" />
<PackageReference Include="Carter" Version="8.0.0" /> <PackageReference Include="Carter" Version="8.1.0" />
<PackageReference Include="FluentValidation" Version="11.9.0" /> <PackageReference Include="FluentValidation" Version="11.10.0" />
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="11.9.0" /> <PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="11.10.0" />
<PackageReference Include="MediatR.Extensions.Autofac.DependencyInjection" Version="12.0.0" /> <PackageReference Include="MediatR.Extensions.Autofac.DependencyInjection" Version="12.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.4" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.8" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="8.0.4" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="8.0.8" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.4"> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.8">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.4"> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.8">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Autofac" Version="8.0.0" /> <PackageReference Include="Autofac" Version="8.1.0" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="9.0.0" /> <PackageReference Include="Autofac.Extensions.DependencyInjection" Version="10.0.0" />
<PackageReference Include="Elmah.Io.AspNetCore.Serilog" Version="5.0.17" /> <PackageReference Include="Elmah.Io.AspNetCore.Serilog" Version="5.1.23" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.4" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.8" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="8.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.20.1" /> <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.21.0" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.2" /> <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.4" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="8.0.0" />
<PackageReference Include="Sentry.Serilog" Version="4.4.0" /> <PackageReference Include="Sentry.Serilog" Version="4.11.0" />
<PackageReference Include="Serilog" Version="3.1.1" /> <PackageReference Include="Serilog" Version="4.0.1" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.1" /> <PackageReference Include="Serilog.AspNetCore" Version="8.0.2" />
<PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" /> <PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
<PackageReference Include="Serilog.Sinks.PostgreSQL" Version="2.3.0" /> <PackageReference Include="Serilog.Sinks.PostgreSQL" Version="2.3.0" />
<PackageReference Include="Serilog.Sinks.Seq" Version="7.0.0" /> <PackageReference Include="Serilog.Sinks.Seq" Version="8.0.0" />
<PackageReference Include="Serilog.Sinks.ElmahIo" Version="5.0.38" /> <PackageReference Include="Serilog.Sinks.ElmahIo" Version="5.1.43" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" /> <PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
<PackageReference Include="StackExchange.Redis.Extensions.AspNetCore" Version="10.2.0" /> <PackageReference Include="StackExchange.Redis.Extensions.AspNetCore" Version="10.2.0" />
<PackageReference Include="StackExchange.Redis.Extensions.Core" Version="10.2.0" /> <PackageReference Include="StackExchange.Redis.Extensions.Core" Version="10.2.0" />
<PackageReference Include="StackExchange.Redis.Extensions.Newtonsoft" Version="10.2.0" /> <PackageReference Include="StackExchange.Redis.Extensions.Newtonsoft" Version="10.2.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="6.8.0" />
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="6.5.0" /> <PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="6.8.0" />
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="8.0.1" /> <PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="8.0.2" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.6" /> <PackageReference Include="System.Data.SqlClient" Version="4.8.6" />
<PackageReference Include="System.Drawing.Common" Version="8.0.4" /> <PackageReference Include="System.Drawing.Common" Version="8.0.8" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -7,6 +7,7 @@ builder.Host.UseSerilog();
LoggerConfig.ConfigureSerilog(); LoggerConfig.ConfigureSerilog();
string env = builder.Environment.IsDevelopment() == true ? "Development" : "Production"; string env = builder.Environment.IsDevelopment() == true ? "Development" : "Production";
builder.Host.UseContentRoot(Directory.GetCurrentDirectory()); builder.Host.UseContentRoot(Directory.GetCurrentDirectory());
if (builder.Environment.IsDevelopment()) if (builder.Environment.IsDevelopment())
{ {
string projectName = "Vesmeh"; string projectName = "Vesmeh";
@ -41,7 +42,6 @@ builder.Services.AddMarten(configuration,builder.Environment);
builder.Services.AddCarter(); builder.Services.AddCarter();
Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense("NjU5MUAzMTM5MmUzMTJlMzBmYlFPZXRJVThMS20zaFlBdjdKMnlKeGJRQng4b0lURDZ1Rk40akFHbnVrPQ==");
builder.Host.ConfigureContainer<ContainerBuilder>(builder => builder.Host.ConfigureContainer<ContainerBuilder>(builder =>
@ -96,12 +96,12 @@ builder.Host.ConfigureContainer<ContainerBuilder>(builder =>
var app = builder.Build(); var app = builder.Build();
// Configure the HTTP request pipeline. // Configure the HTTP request pipeline.
//app.UseCustomSwagger(siteSetting.BaseUrl); app.UseCustomSwagger(siteSetting.BaseUrl);
app.UseSwagger();
app.MapScalarUi(); app.MapScalarUi();
//app.UseSwagger();
//app.UseSwaggerUI(); //app.UseSwaggerUI();
if (app.Environment.IsProduction()) if (app.Environment.IsProduction())

View File

@ -0,0 +1 @@
9167d171-2373-44c9-9fa5-a91858e9854d

View File

@ -3,24 +3,17 @@ using Netina.Repository.Abstracts;
namespace Netina.Api.Services; namespace Netina.Api.Services;
public class CurrentUserService : ICurrentUserService public class CurrentUserService(IHttpContextAccessor httpContextAccessor) : ICurrentUserService
{ {
private readonly IHttpContextAccessor _httpContextAccessor; public string? UserId => httpContextAccessor.HttpContext?.User?.FindFirstValue(ClaimTypes.NameIdentifier);
public string? RoleName => httpContextAccessor.HttpContext?.User?.FindFirstValue(ClaimTypes.Role);
public CurrentUserService(IHttpContextAccessor httpContextAccessor) public string? UserName => httpContextAccessor.HttpContext?.User?.FindFirstValue(ClaimTypes.Name);
{ public string? DeviceId => GetDeviceId(httpContextAccessor.HttpContext);
_httpContextAccessor = httpContextAccessor;
}
public string? UserId => _httpContextAccessor.HttpContext?.User?.FindFirstValue(ClaimTypes.NameIdentifier);
public string? RoleName => _httpContextAccessor.HttpContext?.User?.FindFirstValue(ClaimTypes.Role);
public string? UserName => _httpContextAccessor.HttpContext?.User?.FindFirstValue(ClaimTypes.Name);
public string? DeviceId => GetDeviceId(_httpContextAccessor.HttpContext);
public bool IsAuthorized => GetAuthorized(); public bool IsAuthorized => GetAuthorized();
public JwtSecurityToken? JwtToken => GetJwtToken(); public JwtSecurityToken? JwtToken => GetJwtToken();
private JwtSecurityToken? GetJwtToken() private JwtSecurityToken? GetJwtToken()
{ {
var stream = _httpContextAccessor.HttpContext?.Request.Headers.Authorization.FirstOrDefault(); var stream = httpContextAccessor.HttpContext?.Request.Headers.Authorization.FirstOrDefault();
if (stream == null) if (stream == null)
return null; return null;
var handler = new JwtSecurityTokenHandler(); var handler = new JwtSecurityTokenHandler();
@ -28,7 +21,7 @@ public class CurrentUserService : ICurrentUserService
return jsonToken as JwtSecurityToken; return jsonToken as JwtSecurityToken;
} }
public List<string>? Permissions => _httpContextAccessor.HttpContext?.User?.FindAll("Permission")?.Select(c => c.Value)?.ToList(); public List<string>? Permissions => httpContextAccessor.HttpContext?.User?.FindAll("Permission")?.Select(c => c.Value)?.ToList();
private string? GetDeviceId(HttpContext? context) private string? GetDeviceId(HttpContext? context)
{ {
@ -52,9 +45,9 @@ public class CurrentUserService : ICurrentUserService
private bool GetAuthorized() private bool GetAuthorized()
{ {
if (_httpContextAccessor.HttpContext?.User.Identity == null) if (httpContextAccessor.HttpContext?.User.Identity == null)
return false; return false;
return _httpContextAccessor.HttpContext.User.Identity.IsAuthenticated; return httpContextAccessor.HttpContext.User.Identity.IsAuthenticated;
} }

View File

@ -1,7 +1,4 @@
using Netina.Common.Models.Api; namespace Netina.Api.WebFramework.Bases;
using Netina.Core.Models.Api;
namespace Netina.Api.WebFramework.Bases;
public class ApiResultFactory public class ApiResultFactory
{ {

View File

@ -1,23 +1,13 @@
using Netina.Common.Models.Entity; namespace Netina.Api.WebFramework.Bases;
using Netina.Common.Models.Exception;
using Netina.Common.Models.Mapper;
using Netina.Repository.Repositories.Base.Contracts;
namespace Netina.Api.WebFramework.Bases;
public class CrudEndpoint<TEntity,TGetAllQuery,TGetOneQuery,TCreateCommand,TUpdateCommand,TDeleteCommand> where TEntity : ApiEntity, new() public class CrudEndpoint<TEntity, TGetAllQuery, TGetOneQuery, TCreateCommand, TUpdateCommand, TDeleteCommand>(
string endpointName)
where TEntity : ApiEntity, new()
{ {
private readonly string _endpointName;
public CrudEndpoint(string endpointName)
{
_endpointName = endpointName;
}
public virtual void AddRoutes(IEndpointRouteBuilder app) public virtual void AddRoutes(IEndpointRouteBuilder app)
{ {
var group = app.NewVersionedApi(_endpointName).MapGroup($"api/{_endpointName}"); var group = app.NewVersionedApi(endpointName).MapGroup($"api/{endpointName}");
group.MapGet("", GetAllAsync) group.MapGet("", GetAllAsync)
.WithDisplayName("GetAll") .WithDisplayName("GetAll")
@ -83,16 +73,11 @@ public class BaseController : ControllerBase
} }
[Authorize(AuthenticationSchemes = "Bearer")] [Authorize(AuthenticationSchemes = "Bearer")]
public class CrudController<TDto, TEntity> : BaseController public class CrudController<TDto, TEntity>(IRepositoryWrapper repositoryWrapper) : BaseController
where TDto : BaseDto<TDto, TEntity>, new() where TDto : BaseDto<TDto, TEntity>, new()
where TEntity : ApiEntity, new() where TEntity : ApiEntity, new()
{ {
protected readonly IRepositoryWrapper _repositoryWrapper; protected readonly IRepositoryWrapper _repositoryWrapper = repositoryWrapper;
public CrudController(IRepositoryWrapper repositoryWrapper)
{
_repositoryWrapper = repositoryWrapper;
}
// GET:Get All Entity // GET:Get All Entity
[HttpGet] [HttpGet]
@ -168,15 +153,10 @@ public class CrudController<TDto, TEntity> : BaseController
} }
[Authorize(AuthenticationSchemes = "Bearer")] [Authorize(AuthenticationSchemes = "Bearer")]
public class CrudController<TEntity> : BaseController public class CrudController<TEntity>(IRepositoryWrapper repositoryWrapper) : BaseController
where TEntity : ApiEntity, new() where TEntity : ApiEntity, new()
{ {
protected readonly IRepositoryWrapper _repositoryWrapper; protected readonly IRepositoryWrapper _repositoryWrapper = repositoryWrapper;
public CrudController(IRepositoryWrapper repositoryWrapper)
{
_repositoryWrapper = repositoryWrapper;
}
// GET:Get All Entity // GET:Get All Entity
[HttpGet] [HttpGet]

View File

@ -1,6 +1,4 @@
using Netina.Infrastructure.Models; namespace Netina.Api.WebFramework.Configurations;
namespace Netina.Api.WebFramework.Configurations;
public static class LoggerConfig public static class LoggerConfig
{ {

View File

@ -52,14 +52,14 @@ public static class ServiceExtensions
{ {
new() new()
{ {
Hosts = new[] Hosts =
{ [
new RedisHost new RedisHost
{ {
Port = siteSettings.MasterRedisConfiguration.Port, Port = siteSettings.MasterRedisConfiguration.Port,
Host = siteSettings.MasterRedisConfiguration.Host Host = siteSettings.MasterRedisConfiguration.Host
} }
}, ],
Password = siteSettings.MasterRedisConfiguration.Password, Password = siteSettings.MasterRedisConfiguration.Password,
Ssl = false Ssl = false
} }

View File

@ -1,7 +1,4 @@
using Netina.Common.Models.Api; using Refit;
using Netina.Common.Models.Exception;
using Netina.Core.Models.Api;
using Refit;
namespace Netina.Api.WebFramework.MiddleWares; namespace Netina.Api.WebFramework.MiddleWares;
@ -13,22 +10,11 @@ public static class ExceptionHandlerMiddlewareExtensions
} }
} }
public class ExceptionHandlerMiddleware public class ExceptionHandlerMiddleware(
RequestDelegate next,
IWebHostEnvironment env,
ILogger<ExceptionHandlerMiddleware> logger)
{ {
private readonly IWebHostEnvironment _env;
private readonly ILogger<ExceptionHandlerMiddleware> _logger;
private readonly RequestDelegate _next;
public ExceptionHandlerMiddleware(
RequestDelegate next,
IWebHostEnvironment env,
ILogger<ExceptionHandlerMiddleware> logger)
{
_next = next;
_env = env;
_logger = logger;
}
public async Task Invoke(HttpContext context) public async Task Invoke(HttpContext context)
{ {
string message = null; string message = null;
@ -37,15 +23,17 @@ public class ExceptionHandlerMiddleware
try try
{ {
await _next(context); await next(context);
} }
catch (BaseApiException exception) catch (BaseApiException exception)
{ {
_logger.LogError(exception, exception.Message); logger.LogError(exception, exception.Message);
httpStatusCode = exception.HttpStatusCode; httpStatusCode = exception.ApiStatusCode == ApiResultStatusCode.NotFound ? HttpStatusCode.NotFound :
exception.ApiStatusCode == ApiResultStatusCode.BadRequest ?
HttpStatusCode.BadRequest : exception.HttpStatusCode;
apiStatusCode = exception.ApiStatusCode; apiStatusCode = exception.ApiStatusCode;
if (_env.IsDevelopment()) if (env.IsDevelopment())
{ {
var dic = new Dictionary<string, string> var dic = new Dictionary<string, string>
{ {
@ -83,19 +71,19 @@ public class ExceptionHandlerMiddleware
} }
catch (SecurityTokenExpiredException exception) catch (SecurityTokenExpiredException exception)
{ {
_logger.LogError(exception, exception.Message); logger.LogError(exception, exception.Message);
SetUnAuthorizeResponse(exception); SetUnAuthorizeResponse(exception);
await WriteToResponseAsync(); await WriteToResponseAsync();
} }
catch (UnauthorizedAccessException exception) catch (UnauthorizedAccessException exception)
{ {
_logger.LogError(exception, exception.Message); logger.LogError(exception, exception.Message);
SetUnAuthorizeResponse(exception); SetUnAuthorizeResponse(exception);
await WriteToResponseAsync(); await WriteToResponseAsync();
} }
catch (ApiException apiException) catch (ApiException apiException)
{ {
_logger.LogError(apiException, apiException.Message); logger.LogError(apiException, apiException.Message);
httpStatusCode = HttpStatusCode.InternalServerError; httpStatusCode = HttpStatusCode.InternalServerError;
apiStatusCode = ApiResultStatusCode.RefitError; apiStatusCode = ApiResultStatusCode.RefitError;
@ -106,9 +94,9 @@ public class ExceptionHandlerMiddleware
} }
catch (Exception exception) catch (Exception exception)
{ {
_logger.LogError(exception, exception.Message); logger.LogError(exception, exception.Message);
if (_env.IsDevelopment()) if (env.IsDevelopment())
{ {
if (exception?.InnerException?.Message != null) if (exception?.InnerException?.Message != null)
{ {
@ -145,7 +133,7 @@ public class ExceptionHandlerMiddleware
}); });
if (httpStatusCode == HttpStatusCode.InternalServerError) if (httpStatusCode == HttpStatusCode.InternalServerError)
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError; context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
else else
context.Response.StatusCode = (int)httpStatusCode; context.Response.StatusCode = (int)httpStatusCode;
context.Response.ContentType = "application/json"; context.Response.ContentType = "application/json";
@ -186,7 +174,7 @@ public class ExceptionHandlerMiddleware
httpStatusCode = HttpStatusCode.Unauthorized; httpStatusCode = HttpStatusCode.Unauthorized;
apiStatusCode = ApiResultStatusCode.UnAuthorized; apiStatusCode = ApiResultStatusCode.UnAuthorized;
if (_env.IsDevelopment()) if (env.IsDevelopment())
{ {
var dic = new Dictionary<string, string> var dic = new Dictionary<string, string>
{ {

View File

@ -8,28 +8,19 @@ public static class PerformanceMiddlewareExtensions
} }
} }
public class PerformanceMiddleware public class PerformanceMiddleware(
RequestDelegate next,
ILogger<ExceptionHandlerMiddleware> logger)
{ {
private readonly ILogger<ExceptionHandlerMiddleware> _logger; private readonly Stopwatch _timer = new();
private readonly RequestDelegate _next;
private readonly Stopwatch _timer;
public PerformanceMiddleware(
RequestDelegate next,
ILogger<ExceptionHandlerMiddleware> logger)
{
_next = next;
_logger = logger;
_timer = new Stopwatch();
}
public async System.Threading.Tasks.Task Invoke(HttpContext context) public async System.Threading.Tasks.Task Invoke(HttpContext context)
{ {
_timer.Start(); _timer.Start();
await _next(context); await next(context);
_timer.Stop(); _timer.Stop();
var elapsedMilliseconds = _timer.ElapsedMilliseconds; var elapsedMilliseconds = _timer.ElapsedMilliseconds;
_logger.LogWarning($"REQUEST TIMER : {elapsedMilliseconds}"); logger.LogWarning($"REQUEST TIMER : {elapsedMilliseconds}");
} }
} }

View File

@ -27,7 +27,7 @@ public static class ScalarUiConfiguration
<!-- Optional: You can set a full configuration object like this: --> <!-- Optional: You can set a full configuration object like this: -->
<script> <script>
var configuration = { var configuration = {
theme: 'bluePlanet', theme: 'mars',
} }
document.getElementById('api-reference').dataset.configuration = document.getElementById('api-reference').dataset.configuration =

View File

@ -1,6 +1,5 @@
using Microsoft.AspNetCore.Mvc.Controllers; using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Models;
using Netina.Common.Extensions;
using Pluralize.NET; using Pluralize.NET;
using Swashbuckle.AspNetCore.SwaggerGen; using Swashbuckle.AspNetCore.SwaggerGen;
using Swashbuckle.AspNetCore.SwaggerUI; using Swashbuckle.AspNetCore.SwaggerUI;
@ -19,9 +18,9 @@ public static class SwaggerConfiguration
new OpenApiInfo new OpenApiInfo
{ {
Version = "v1", Version = "v1",
Title = "iGarson Api Dacument", Title = "Netina Api Document",
Description = "iGarson api for clients that wana use", Description = "Netina api for netina clients , like shops , websites and apps",
License = new OpenApiLicense { Name = "Vira Safir Fanavar " }, License = new OpenApiLicense { Name = "Vira Safir Fanavar" },
Contact = new OpenApiContact Contact = new OpenApiContact
{ {
Name = "Amir Hossein Khademi", Name = "Amir Hossein Khademi",
@ -139,17 +138,12 @@ public class SetVersionInPaths : IDocumentFilter
} }
} }
public class UnauthorizedResponsesOperationFilter : IOperationFilter public class UnauthorizedResponsesOperationFilter(
bool includeUnauthorizedAndForbiddenResponses,
string schemeName = "Bearer")
: IOperationFilter
{ {
private readonly bool includeUnauthorizedAndForbiddenResponses; private readonly string schemeName = schemeName;
private readonly string schemeName;
public UnauthorizedResponsesOperationFilter(bool includeUnauthorizedAndForbiddenResponses,
string schemeName = "Bearer")
{
this.includeUnauthorizedAndForbiddenResponses = includeUnauthorizedAndForbiddenResponses;
this.schemeName = schemeName;
}
public void Apply(OpenApiOperation operation, OperationFilterContext context) public void Apply(OpenApiOperation operation, OperationFilterContext context)
{ {

View File

@ -1,14 +1,23 @@
using System.Web; using System.Net;
using System.Xml.Linq; using System.Web;
namespace Netina.Common.Extensions namespace Netina.Common.Extensions
{ {
public static class StringExtensions public static class StringExtensions
{ {
public static bool IsNullOrEmpty(this string value)
=> string.IsNullOrEmpty(value);
public static string GetSlug(string title) public static string GetSlug(string title)
{ {
return HttpUtility.UrlEncode(title.Replace(' ', '-')); var splits = title.Split("/");
string outPut = string.Empty;
foreach (var split in splits)
outPut = outPut.IsNullOrEmpty() ? split : string.Concat(outPut, "/", WebUtility.UrlEncode( split.Replace(' ', '-')));
return outPut;
} }
public static string ToPriceWhitPriceType(this long price, string priceType) public static string ToPriceWhitPriceType(this long price, string priceType)
{ {
return price.ToString("N0") + " " + priceType; return price.ToString("N0") + " " + priceType;

View File

@ -19,23 +19,23 @@ public class MartenEntity : IMartenEntity
public bool Equals(ApiEntity other) //public bool Equals(ApiEntity other)
{ //{
if (ReferenceEquals(null, other)) return false; // if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true; // if (ReferenceEquals(this, other)) return true;
return Id.Equals(other.Id); // return Id.Equals(other.Id);
} //}
public override bool Equals(object obj) //public override bool Equals(object obj)
{ //{
if (ReferenceEquals(null, obj)) return false; // if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true; // if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false; // if (obj.GetType() != this.GetType()) return false;
return Equals((ApiEntity)obj); // return Equals((ApiEntity)obj);
} //}
public override int GetHashCode() //public override int GetHashCode()
{ //{
return Id.GetHashCode(); // return Id.GetHashCode();
} //}
} }

View File

@ -3,15 +3,14 @@
[AttributeUsage(AttributeTargets.Class)] [AttributeUsage(AttributeTargets.Class)]
public class PageClassDisplay : Attribute public class PageClassDisplay : Attribute
{ {
private readonly string _description;
private readonly string _name; private readonly string _name;
private readonly string _description;
public PageClassDisplay(string name, string description) public PageClassDisplay(string name, string description)
{ {
_name = name; _name = name;
_description = description; _description = description;
} }
public string GetName() public string GetName()
{ {
return _name; return _name;

View File

@ -1,22 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
</PropertyGroup> <LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="MD.PersianDateTime.Standard" Version="2.5.0" /> <PackageReference Include="MD.PersianDateTime.Standard" Version="2.5.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" /> <PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.5.1" /> <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.0.2" />
</ItemGroup> </ItemGroup>
<!--<PropertyGroup> <!--<PropertyGroup>
<TargetFramework>net5.0</TargetFramework> <TargetFramework>net5.0</TargetFramework>
<LangVersion>10</LangVersion> <LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup> </PropertyGroup>

View File

@ -2,8 +2,12 @@
public interface IPageService : IScopedDependency public interface IPageService : IScopedDependency
{ {
Task<BasePageSDto> GetPageAsync(Guid? id = null, string? pageName = null, string? pageSlug = null, string? type = null, CancellationToken cancellationToken = default); Task<BasePageLDto> GetPageAsync(Guid? id = null, string? pageName = null, string? pageSlug = null, string? type = null, CancellationToken cancellationToken = default);
Task<List<BasePageSDto>> GetPagesAsync(CancellationToken cancellationToken = default); Task<List<BasePageSDto>> GetPagesAsync(CancellationToken cancellationToken = default);
Task<bool> CreatePageAsync(PageActionRequestDto entity, CancellationToken cancellationToken = default); Task<bool> CreatePageAsync(PageActionRequestDto entity, CancellationToken cancellationToken = default);
Task<bool> UpdatePageAsync(PageActionRequestDto entity, CancellationToken cancellationToken = default);
Task<bool> DeletePageAsync(Guid id, CancellationToken cancellationToken = default); Task<bool> DeletePageAsync(Guid id, CancellationToken cancellationToken = default);
Task<string> CheckRedirectAsync(string oldUrl, CancellationToken cancellationToken);
Task<bool> CheckDeletedAsync(string url, CancellationToken cancellationToken);
} }

View File

@ -1,53 +1,32 @@
namespace Netina.Core.BaseServices; namespace Netina.Core.BaseServices;
public class AccountService : IAccountService public class AccountService(
UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> userSignInManager,
IJwtService jwtService,
ICurrentUserService currentUserService,
IRepositoryWrapper repositoryWrapper,
ISmsService smsService,
IUserService managerUserService)
: IAccountService
{ {
private readonly UserManager<ApplicationUser> _userManager;
private readonly SignInManager<ApplicationUser> _userSignInManager;
private readonly IJwtService _jwtService;
private readonly ICurrentUserService _currentUserService;
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly ISmsService _smsService;
private readonly IUserService _managerUserService;
public AccountService(
UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> userSignInManager,
IJwtService jwtService,
ICurrentUserService currentUserService,
IRepositoryWrapper repositoryWrapper,
ISmsService smsService,
IUserService managerUserService)
{
_userManager = userManager;
_userSignInManager = userSignInManager;
_jwtService = jwtService;
_currentUserService = currentUserService;
_repositoryWrapper = repositoryWrapper;
_smsService = smsService;
_managerUserService = managerUserService;
}
public async Task<bool> ForgetPasswordAsync(string phoneNumber) public async Task<bool> ForgetPasswordAsync(string phoneNumber)
{ {
var user = await _userManager.FindByNameAsync(phoneNumber); var user = await userManager.FindByNameAsync(phoneNumber);
if (user != null) if (user != null)
{ {
var rand = new Random(DateTime.Now.Millisecond); var rand = new Random(DateTime.Now.Millisecond);
var newPass = rand.Next(1000000, 9000000).ToString(); var newPass = rand.Next(1000000, 9000000).ToString();
if (!user.PhoneNumberConfirmed) if (!user.PhoneNumberConfirmed)
throw new AppException("شماره تلفن شما تایید نشده است و قابلیت استفاده از فراموشی رمز عبور را ندارید"); throw new AppException("شماره تلفن شما تایید نشده است و قابلیت استفاده از فراموشی رمز عبور را ندارید");
var rp = await _userManager.RemovePasswordAsync(user); var rp = await userManager.RemovePasswordAsync(user);
if (!rp.Succeeded) if (!rp.Succeeded)
throw new AppException(string.Join('-', rp.Errors.Select(e => e.Description))); throw new AppException(string.Join('-', rp.Errors.Select(e => e.Description)));
var ap = await _userManager.AddPasswordAsync(user, newPass); var ap = await userManager.AddPasswordAsync(user, newPass);
if (!ap.Succeeded) if (!ap.Succeeded)
throw new AppException(string.Join('-', ap.Errors.Select(e => e.Description))); throw new AppException(string.Join('-', ap.Errors.Select(e => e.Description)));
await _smsService.SendForgerPasswordAsync(user.PhoneNumber, newPass); await smsService.SendForgerPasswordAsync(user.PhoneNumber, newPass);
return true; return true;
} }
@ -56,7 +35,7 @@ public class AccountService : IAccountService
public async Task<bool> CheckMemberShipAsync(string phoneNumber) public async Task<bool> CheckMemberShipAsync(string phoneNumber)
{ {
var user = await _userManager.FindByNameAsync(phoneNumber); var user = await userManager.FindByNameAsync(phoneNumber);
if (user == null) if (user == null)
return false; return false;
return true; return true;
@ -67,23 +46,23 @@ public class AccountService : IAccountService
var newPhoneNumber = StringExtensions.CheckPhoneNumber(phoneNumber); var newPhoneNumber = StringExtensions.CheckPhoneNumber(phoneNumber);
if (!PhoneNumberExtensions.CheckPhoneNumber(newPhoneNumber)) if (!PhoneNumberExtensions.CheckPhoneNumber(newPhoneNumber))
throw new AppException("شماره تلفن ارسالی اشتباه است"); throw new AppException("شماره تلفن ارسالی اشتباه است");
var user = await _userManager.FindByNameAsync(newPhoneNumber); var user = await userManager.FindByNameAsync(newPhoneNumber);
if (user == null) if (user == null)
user = await _managerUserService.CreateUserAsync(phoneNumber); user = await managerUserService.CreateUserAsync(phoneNumber);
var token = await _userManager.GenerateTwoFactorTokenAsync(user, "Phone"); var token = await userManager.GenerateTwoFactorTokenAsync(user, "Phone");
await _smsService.SendVerifyCodeAsync(newPhoneNumber, token); await smsService.SendVerifyCodeAsync(newPhoneNumber, token);
return new VerifyCodeResponseDto { SignUpStatus = SignUpStatus.StartSignOn }; return new VerifyCodeResponseDto { SignUpStatus = SignUpStatus.StartSignOn };
} }
public async Task<AccessToken<ApplicationUserSDto>> LoginWithPasswordAsync(string userName, string password, CancellationToken cancellationToken) public async Task<AccessToken<ApplicationUserSDto>> LoginWithPasswordAsync(string userName, string password, CancellationToken cancellationToken)
{ {
var result = await _userSignInManager.PasswordSignInAsync(userName, password, false, false); var result = await userSignInManager.PasswordSignInAsync(userName, password, false, false);
if (!result.Succeeded) if (!result.Succeeded)
throw new AppException("رمز عبور یا نام کاربری اشتباه است"); throw new AppException("رمز عبور یا نام کاربری اشتباه است");
var admin = await _userManager.FindByNameAsync(userName); var admin = await userManager.FindByNameAsync(userName);
if (admin == null) if (admin == null)
throw new AppException("نام کاربری یا رمز عبور اشتباه است"); throw new AppException("نام کاربری یا رمز عبور اشتباه است");
return await CompleteLogin(admin, cancellationToken); return await CompleteLogin(admin, cancellationToken);
@ -91,11 +70,11 @@ public class AccountService : IAccountService
public async Task<AccessToken<ApplicationUserSDto>> LoginWithVerifyCodeAsync(string userName, string verifyCode, CancellationToken cancellationToken) public async Task<AccessToken<ApplicationUserSDto>> LoginWithVerifyCodeAsync(string userName, string verifyCode, CancellationToken cancellationToken)
{ {
var user = await _userManager.FindByNameAsync(userName); var user = await userManager.FindByNameAsync(userName);
if (user == null) if (user == null)
throw new AppException("نام کاربری یا کد ارسالی اشتباه است", ApiResultStatusCode.NotFound); throw new AppException("نام کاربری یا کد ارسالی اشتباه است", ApiResultStatusCode.NotFound);
var verfiyResult = await _userManager.VerifyTwoFactorTokenAsync(user, "Phone", verifyCode); var verfiyResult = await userManager.VerifyTwoFactorTokenAsync(user, "Phone", verifyCode);
if (verifyCode == "859585") if (verifyCode == "859585")
verfiyResult = true; verfiyResult = true;
if (!verfiyResult) if (!verfiyResult)
@ -104,7 +83,7 @@ public class AccountService : IAccountService
{ {
user.PhoneNumberConfirmed = true; user.PhoneNumberConfirmed = true;
user.SignUpStatus = SignUpStatus.PhoneNumberVerified; user.SignUpStatus = SignUpStatus.PhoneNumberVerified;
var result = await _userManager.UpdateAsync(user); var result = await userManager.UpdateAsync(user);
if (!result.Succeeded) if (!result.Succeeded)
throw new AppException(string.Join('|', result.Errors)); throw new AppException(string.Join('|', result.Errors));
} }
@ -113,9 +92,9 @@ public class AccountService : IAccountService
public async Task<AccessToken<ApplicationUserSDto>> CompleteSignUpAsync(SignUpRequestDto requestDto, CancellationToken cancellationToken) public async Task<AccessToken<ApplicationUserSDto>> CompleteSignUpAsync(SignUpRequestDto requestDto, CancellationToken cancellationToken)
{ {
if (_currentUserService.UserId == null) if (currentUserService.UserId == null)
throw new AppException("User Id is null"); throw new AppException("User Id is null");
var user = await _userManager.FindByIdAsync(_currentUserService.UserId); var user = await userManager.FindByIdAsync(currentUserService.UserId);
if (user == null) if (user == null)
throw new AppException("User not found", ApiResultStatusCode.NotFound); throw new AppException("User not found", ApiResultStatusCode.NotFound);
if (user.SignUpStatus == SignUpStatus.SignUpCompleted) if (user.SignUpStatus == SignUpStatus.SignUpCompleted)
@ -132,19 +111,19 @@ public class AccountService : IAccountService
user.FirstName = requestDto.FirstName; user.FirstName = requestDto.FirstName;
user.LastName = requestDto.LastName; user.LastName = requestDto.LastName;
user.SignUpStatus = SignUpStatus.SignUpCompleted; user.SignUpStatus = SignUpStatus.SignUpCompleted;
var result = await _userManager.UpdateAsync(user); var result = await userManager.UpdateAsync(user);
if (!result.Succeeded) if (!result.Succeeded)
throw new AppException(string.Join('|', result.Errors.Select(e => e.Description))); throw new AppException(string.Join('|', result.Errors.Select(e => e.Description)));
var roleResult = await _userManager.AddToRoleAsync(user, "Customer"); var roleResult = await userManager.AddToRoleAsync(user, "Customer");
if (!roleResult.Succeeded) if (!roleResult.Succeeded)
throw new AppException(string.Join('|', roleResult.Errors.Select(e => e.Description))); throw new AppException(string.Join('|', roleResult.Errors.Select(e => e.Description)));
_repositoryWrapper.SetRepository<Customer>() repositoryWrapper.SetRepository<Customer>()
.Add(new Customer .Add(new Customer
{ {
UserId = user.Id, UserId = user.Id,
}); });
await _repositoryWrapper.SaveChangesAsync(default); await repositoryWrapper.SaveChangesAsync(default);
return await CompleteLogin(user, cancellationToken); return await CompleteLogin(user, cancellationToken);
} }
@ -153,8 +132,8 @@ public class AccountService : IAccountService
private async Task<AccessToken<ApplicationUserSDto>> CompleteLogin(ApplicationUser user, CancellationToken cancellationToken) private async Task<AccessToken<ApplicationUserSDto>> CompleteLogin(ApplicationUser user, CancellationToken cancellationToken)
{ {
AccessToken<ApplicationUserSDto> jwt; AccessToken<ApplicationUserSDto> jwt;
var role = await _userManager.GetRolesAsync(user); var role = await userManager.GetRolesAsync(user);
jwt = await _jwtService.Generate<ApplicationUserSDto, ApplicationUser>(user, role.ToList()); jwt = await jwtService.Generate<ApplicationUserSDto, ApplicationUser>(user, role.ToList());
jwt.User.RoleName = jwt.RoleName; jwt.User.RoleName = jwt.RoleName;
return jwt; return jwt;
} }

View File

@ -2,38 +2,31 @@
namespace Netina.Core.BaseServices; namespace Netina.Core.BaseServices;
public class DashboardService : IDashboardService public class DashboardService(IRepositoryWrapper repositoryWrapper, UserManager<ApplicationUser> userManager)
: IDashboardService
{ {
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly UserManager<ApplicationUser> _userManager;
public DashboardService(IRepositoryWrapper repositoryWrapper,UserManager<ApplicationUser> userManager)
{
_repositoryWrapper = repositoryWrapper;
_userManager = userManager;
}
public async Task<HomeDashboardDto> GetHomeDashboardAsyncTask(CancellationToken cancellationToken = default) public async Task<HomeDashboardDto> GetHomeDashboardAsyncTask(CancellationToken cancellationToken = default)
{ {
var response = new HomeDashboardDto var response = new HomeDashboardDto
{ {
BlogsCount = await _repositoryWrapper.SetRepository<Blog>() BlogsCount = await repositoryWrapper.SetRepository<Blog>()
.TableNoTracking .TableNoTracking
.CountAsync(cancellationToken), .CountAsync(cancellationToken),
ProductsCount = await _repositoryWrapper.SetRepository<Product>() ProductsCount = await repositoryWrapper.SetRepository<Product>()
.TableNoTracking .TableNoTracking
.CountAsync(cancellationToken), .CountAsync(cancellationToken),
TodayOrdersCount = await _repositoryWrapper.SetRepository<Order>() TodayOrdersCount = await repositoryWrapper.SetRepository<Order>()
.TableNoTracking .TableNoTracking
.Where(o => o.OrderAt.Date == DateTime.Today.Date) .Where(o => o.OrderAt.Date == DateTime.Today.Date)
.CountAsync(cancellationToken), .CountAsync(cancellationToken),
UnSubmittedOrdersCount = await _repositoryWrapper.SetRepository<Order>() UnSubmittedOrdersCount = await repositoryWrapper.SetRepository<Order>()
.TableNoTracking .TableNoTracking
.Where(o => o.OrderStatus == OrderStatus.Paid || o.OrderStatus == OrderStatus.Submitted) .Where(o => o.OrderStatus == OrderStatus.Paid || o.OrderStatus == OrderStatus.Submitted)
.CountAsync(cancellationToken), .CountAsync(cancellationToken),
BrandsCount = await _repositoryWrapper.SetRepository<Brand>() BrandsCount = await repositoryWrapper.SetRepository<Brand>()
.TableNoTracking .TableNoTracking
.CountAsync(cancellationToken), .CountAsync(cancellationToken),
SubscribersCount = await _userManager.Users.CountAsync(cancellationToken) SubscribersCount = await userManager.Users.CountAsync(cancellationToken)
}; };
return response; return response;
@ -45,19 +38,19 @@ public class DashboardService : IDashboardService
DateTime endOfThisMonth = startOfThisMonth.AddMonths(1); DateTime endOfThisMonth = startOfThisMonth.AddMonths(1);
var response = new OrderDashboardDto var response = new OrderDashboardDto
{ {
PayedOrdersCount = await _repositoryWrapper.SetRepository<Order>() PayedOrdersCount = await repositoryWrapper.SetRepository<Order>()
.TableNoTracking .TableNoTracking
.Where(o=>o.IsPayed && o.OrderStatus==OrderStatus.Paid) .Where(o=>o.IsPayed && o.OrderStatus==OrderStatus.Paid)
.CountAsync(cancellationToken), .CountAsync(cancellationToken),
ThisMonthOrdersCount = await _repositoryWrapper.SetRepository<Order>() ThisMonthOrdersCount = await repositoryWrapper.SetRepository<Order>()
.TableNoTracking .TableNoTracking
.Where(s => s.OrderAt.Date >= startOfThisMonth.Date && s.OrderAt.Date < endOfThisMonth.Date) .Where(s => s.OrderAt.Date >= startOfThisMonth.Date && s.OrderAt.Date < endOfThisMonth.Date)
.CountAsync(cancellationToken), .CountAsync(cancellationToken),
TodayOrdersCount = await _repositoryWrapper.SetRepository<Order>() TodayOrdersCount = await repositoryWrapper.SetRepository<Order>()
.TableNoTracking .TableNoTracking
.Where(o => o.OrderAt.Date == DateTime.Now.Date) .Where(o => o.OrderAt.Date == DateTime.Now.Date)
.CountAsync(cancellationToken), .CountAsync(cancellationToken),
UnSendOrdersCount = await _repositoryWrapper.SetRepository<Order>() UnSendOrdersCount = await repositoryWrapper.SetRepository<Order>()
.TableNoTracking .TableNoTracking
.Where(o => o.IsPayed && o.OrderStatus == OrderStatus.Processing) .Where(o => o.IsPayed && o.OrderStatus == OrderStatus.Processing)
.CountAsync(cancellationToken) .CountAsync(cancellationToken)

View File

@ -1,21 +1,14 @@
namespace Netina.Core.BaseServices; namespace Netina.Core.BaseServices;
public class JwtService : IJwtService public class JwtService(
IOptionsSnapshot<SiteSettings> siteSettings,
SignInManager<ApplicationUser> userSignInManager,
RoleManager<ApplicationRole> roleManager)
: IJwtService
{ {
private readonly SignInManager<ApplicationUser> _signInManager; private readonly SiteSettings _siteSettings = siteSettings.Value;
private readonly RoleManager<ApplicationRole> _roleManager;
private readonly SiteSettings _siteSettings;
public JwtService(
IOptionsSnapshot<SiteSettings> siteSettings,
SignInManager<ApplicationUser> userSignInManager,
RoleManager<ApplicationRole> roleManager)
{
_signInManager = userSignInManager;
_roleManager = roleManager;
_siteSettings = siteSettings.Value;
}
public async Task<AccessToken<TUser>> Generate<TUser>(TUser user) where TUser : ApplicationUser public async Task<AccessToken<TUser>> Generate<TUser>(TUser user) where TUser : ApplicationUser
{ {
var tokenId = StringExtensions.GetId(8); var tokenId = StringExtensions.GetId(8);
@ -89,7 +82,7 @@ public class JwtService : IJwtService
private async Task<List<Claim>> GetClaims<TUser>(TUser baseUser, string jwtId) where TUser : ApplicationUser private async Task<List<Claim>> GetClaims<TUser>(TUser baseUser, string jwtId) where TUser : ApplicationUser
{ {
var clFac = (await _signInManager.ClaimsFactory.CreateAsync(baseUser)); var clFac = (await userSignInManager.ClaimsFactory.CreateAsync(baseUser));
var claims = new List<Claim>(); var claims = new List<Claim>();
claims.Add(new Claim("JwtID", jwtId)); claims.Add(new Claim("JwtID", jwtId));
claims.Add(new Claim(ClaimTypes.Name, baseUser.UserName)); claims.Add(new Claim(ClaimTypes.Name, baseUser.UserName));
@ -108,10 +101,10 @@ public class JwtService : IJwtService
foreach (var roleName in roleNames) foreach (var roleName in roleNames)
{ {
var applicationRole = await _roleManager.FindByNameAsync(roleName); var applicationRole = await roleManager.FindByNameAsync(roleName);
if(applicationRole==null) if(applicationRole==null)
continue; continue;
var roleClaims = await _roleManager.GetClaimsAsync(applicationRole); var roleClaims = await roleManager.GetClaimsAsync(applicationRole);
claims.AddRange(roleClaims); claims.AddRange(roleClaims);
claims.Add(new Claim(ClaimTypes.Role, applicationRole.EnglishName)); claims.Add(new Claim(ClaimTypes.Role, applicationRole.EnglishName));
claims.Add(new Claim("RoleId", applicationRole.Id.ToString())); claims.Add(new Claim("RoleId", applicationRole.Id.ToString()));

View File

@ -2,42 +2,31 @@
namespace Netina.Core.BaseServices; namespace Netina.Core.BaseServices;
public class PageService : IPageService public class PageService(
IMartenRepositoryWrapper martenRepositoryWrapperWrapper,
ICurrentUserService currentUserService,
ISettingService settingService)
: IPageService
{ {
private readonly IMartenRepositoryWrapper _martenRepositoryWrapper; public async Task<BasePageLDto> GetPageAsync(Guid? id = null,
private readonly ICurrentUserService _currentUserService; string? pageName = null,
string? pageSlug = null,
public PageService(IMartenRepositoryWrapper martenRepositoryWrapperWrapper, ICurrentUserService currentUserService) string? type = null,
{ CancellationToken cancellationToken = default)
_martenRepositoryWrapper = martenRepositoryWrapperWrapper;
_currentUserService = currentUserService;
}
public async Task<BasePageSDto> GetPageAsync(Guid? id = null, string? pageName = null, string? pageSlug = null, string? type = null, CancellationToken cancellationToken = default)
{ {
BasePage? page = null; BasePage? page = null;
if (id != null) if (id != null)
page = await _martenRepositoryWrapper.SetRepository<BasePage>().GetEntityAsync(id.Value, cancellationToken); page = await martenRepositoryWrapperWrapper.SetRepository<BasePage>().GetEntityAsync(id.Value, cancellationToken);
else if (pageSlug != null) else if (pageSlug != null)
page = await _martenRepositoryWrapper.SetRepository<BasePage>().GetEntityAsync(entity => entity.Slug == pageSlug, cancellationToken); page = await martenRepositoryWrapperWrapper.SetRepository<BasePage>().GetEntityAsync(entity => entity.Slug == pageSlug, cancellationToken);
else if (pageName != null) else if (pageName != null)
page = await _martenRepositoryWrapper.SetRepository<BasePage>().GetEntityAsync(entity => entity.Title == pageName, cancellationToken); page = await martenRepositoryWrapperWrapper.SetRepository<BasePage>().GetEntityAsync(entity => entity.Title == pageName, cancellationToken);
else if (type != null) else if (type != null)
page = await _martenRepositoryWrapper.SetRepository<BasePage>().GetEntityAsync(entity => entity.Type == type, cancellationToken); page = await martenRepositoryWrapperWrapper.SetRepository<BasePage>().GetEntityAsync(entity => entity.Type == type, cancellationToken);
if (page == null) if (page == null)
throw new AppException("Page not found", ApiResultStatusCode.NotFound); throw new AppException("Page not found", ApiResultStatusCode.NotFound);
var entityType = Assembly.GetAssembly(typeof(DomainConfig))?.GetType(page.Type); var dto = page.Adapt<BasePageLDto>();
var dto = new BasePageSDto
{
Content = page.Content,
Description = page.Description,
Id = page.Id,
IsCustomPage = page.IsCustomPage,
IsHtmlBasePage = page.IsHtmlBasePage,
Title = page.Title,
Slug = page.Slug,
Data = page.Data
};
return dto; return dto;
} }
@ -45,22 +34,10 @@ public class PageService : IPageService
public async Task<List<BasePageSDto>> GetPagesAsync(CancellationToken cancellationToken = default) public async Task<List<BasePageSDto>> GetPagesAsync(CancellationToken cancellationToken = default)
{ {
List<BasePageSDto> sDtos = new List<BasePageSDto>(); List<BasePageSDto> sDtos = new List<BasePageSDto>();
var pages = await _martenRepositoryWrapper.SetRepository<BasePage>().GetEntitiesAsync(cancellationToken); var pages = await martenRepositoryWrapperWrapper.SetRepository<BasePage>().GetEntitiesAsync(cancellationToken);
foreach (var page in pages) foreach (var page in pages)
{ {
var dto = new BasePageSDto var dto = page.Adapt<BasePageSDto>();
{
Content = page.Content,
Description = page.Description,
Id = page.Id,
IsCustomPage = page.IsCustomPage,
IsHtmlBasePage = page.IsHtmlBasePage,
Title = page.Title,
Slug = page.Slug,
Data = page.Data,
CreatedAt = page.CreatedAt,
ModifiedAt = page.ModifiedAt
};
sDtos.Add(dto); sDtos.Add(dto);
} }
return sDtos; return sDtos;
@ -79,23 +56,61 @@ public class PageService : IPageService
Type = entity.Type, Type = entity.Type,
Slug = entity.Slug, Slug = entity.Slug,
CreatedAt = DateTime.Now, CreatedAt = DateTime.Now,
CreatedBy = _currentUserService.UserName ?? string.Empty CreatedBy = currentUserService.UserName ?? string.Empty,
Indexing = entity.Indexing,
Sections = entity.Sections
}; };
if (!basePage.Type.IsNullOrEmpty()) if (!basePage.Type.IsNullOrEmpty())
{ {
var type = Assembly.GetAssembly(typeof(DomainConfig))?.GetType(entity.Type); var type = Assembly.GetAssembly(typeof(DomainConfig))?.GetType(entity.Type);
basePage.Data = JsonConvert.SerializeObject(((JsonElement)entity.Data).Deserialize(type)); basePage.Data = JsonConvert.SerializeObject(((JsonElement)entity.Data).Deserialize(type));
} }
await _martenRepositoryWrapper.SetRepository<BasePage>().AddOrUpdateEntityAsync(basePage, cancellationToken); await martenRepositoryWrapperWrapper.SetRepository<BasePage>().AddOrUpdateEntityAsync(basePage, cancellationToken);
return true; return true;
} }
public async Task<bool> DeletePageAsync(Guid id, CancellationToken cancellationToken = default) public async Task<bool> DeletePageAsync(Guid id, CancellationToken cancellationToken = default)
{ {
var page = await _martenRepositoryWrapper.SetRepository<BasePage>().GetEntityAsync(p => p.Id == id, cancellationToken); var page = await martenRepositoryWrapperWrapper.SetRepository<BasePage>().GetEntityAsync(p => p.Id == id, cancellationToken);
if (page == null) if (page == null)
throw new AppException("Page not found", ApiResultStatusCode.NotFound); throw new AppException("Page not found", ApiResultStatusCode.NotFound);
await _martenRepositoryWrapper.SetRepository<BasePage>().RemoveEntityAsync(page, cancellationToken); await martenRepositoryWrapperWrapper.SetRepository<BasePage>().RemoveEntityAsync(page, cancellationToken);
return true;
}
public async Task<string> CheckRedirectAsync(string oldUrl, CancellationToken cancellationToken)
{
var setting = await settingService.GetSettingAsync(nameof(PageSetting), cancellationToken);
var oldEncode = StringExtensions.GetSlug(oldUrl);
if (setting is PageSetting pageSetting)
{
var newLink = pageSetting.RedirectItems.FirstOrDefault(f => f.OldUrl.ToLower().Trim() == oldEncode.ToLower().Trim());
if (newLink != null)
{
var response = newLink.NewUrl[0] == '/' ? newLink.NewUrl : $"/{newLink.NewUrl}";
return response;
}
else
throw new BaseApiException(ApiResultStatusCode.NotFound, "Url not found");
}
throw new BaseApiException(ApiResultStatusCode.NotFound, "PageSetting not found");
}
public async Task<bool> CheckDeletedAsync(string url, CancellationToken cancellationToken)
{
var setting = await settingService.GetSettingAsync(nameof(PageSetting), cancellationToken);
if (setting is PageSetting pageSetting)
{
var newLink = pageSetting.DeletedPages.FirstOrDefault(f => f.Url.ToLower().Trim() == url.ToLower().Trim());
return newLink != null;
}
throw new BaseApiException(ApiResultStatusCode.NotFound, "PageSetting not found");
}
public async Task<bool> UpdatePageAsync(PageActionRequestDto entity, CancellationToken cancellationToken = default)
{
var basePage = entity.Adapt<BasePage>();
await martenRepositoryWrapperWrapper.SetRepository<BasePage>().AddOrUpdateEntityAsync(basePage, cancellationToken);
return true; return true;
} }
} }

View File

@ -1,21 +1,16 @@
 
public class SettingService : ISettingService namespace Netina.Core.BaseServices;
public class SettingService(IMartenRepositoryWrapper martenRepositoryWrapper) : ISettingService
{ {
private readonly IMartenRepositoryWrapper _martenRepositoryWrapper;
public SettingService(IMartenRepositoryWrapper martenRepositoryWrapper)
{
_martenRepositoryWrapper = martenRepositoryWrapper;
}
public async Task<object> GetSettingAsync(string settingName, CancellationToken cancellationToken = default) public async Task<object> GetSettingAsync(string settingName, CancellationToken cancellationToken = default)
{ {
var type = Assembly.GetAssembly(typeof(DomainConfig))?.GetType($"Netina.Domain.MartenEntities.Settings.{settingName}"); var type = Assembly.GetAssembly(typeof(DomainConfig))?.GetType($"Netina.Domain.MartenEntities.Settings.{settingName}");
if (type == null) if (type == null)
throw new AppException("Setting not found", ApiResultStatusCode.NotFound); throw new AppException("Setting not found", ApiResultStatusCode.NotFound);
var baseSetting = await _martenRepositoryWrapper.SetRepository<BaseSetting>() var baseSetting = await martenRepositoryWrapper.SetRepository<BaseSetting>()
.GetEntityAsync(s => s.Name == settingName, cancellationToken); .GetEntityAsync(s => s.Name == settingName, cancellationToken);
object? setting; object? setting;
if (baseSetting == null) if (baseSetting == null)
@ -34,7 +29,7 @@ public class SettingService : ISettingService
if (type == null) if (type == null)
throw new AppException("Setting not found", ApiResultStatusCode.NotFound); throw new AppException("Setting not found", ApiResultStatusCode.NotFound);
var baseSetting = await _martenRepositoryWrapper.SetRepository<BaseSetting>() var baseSetting = await martenRepositoryWrapper.SetRepository<BaseSetting>()
.GetEntityAsync(s => s.Name == settingName, cancellationToken); .GetEntityAsync(s => s.Name == settingName, cancellationToken);
if (baseSetting == null) if (baseSetting == null)
@ -51,7 +46,7 @@ public class SettingService : ISettingService
baseSetting.JsonData = JsonConvert.SerializeObject(settingObj.Deserialize(type)); baseSetting.JsonData = JsonConvert.SerializeObject(settingObj.Deserialize(type));
} }
await _martenRepositoryWrapper.SetRepository<BaseSetting>() await martenRepositoryWrapper.SetRepository<BaseSetting>()
.AddOrUpdateEntityAsync(baseSetting, cancellationToken); .AddOrUpdateEntityAsync(baseSetting, cancellationToken);
} }
} }

View File

@ -1,4 +1,5 @@
using System.IO.Compression; using System.IO.Compression;
using System.Net;
using System.Xml; using System.Xml;
using Netina.Core.Models; using Netina.Core.Models;
using Netina.Domain.Entities.ProductCategories; using Netina.Domain.Entities.ProductCategories;
@ -6,23 +7,14 @@ using Netina.Domain.Entities.ProductCategories;
namespace Netina.Core.BaseServices; namespace Netina.Core.BaseServices;
public class SiteMapService : ISiteMapService public class SiteMapService(
IOptionsSnapshot<SiteSettings> snapshot,
IUploadFileService uploadFileService,
IRepositoryWrapper repositoryWrapper,
IPageService pageService) : ISiteMapService
{ {
private readonly IUploadFileService _uploadFileService; private readonly SiteSettings _siteSetting = snapshot.Value;
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly IPageService _pageService;
private readonly SiteSettings _siteSetting;
public SiteMapService(IOptionsSnapshot<SiteSettings> snapshot,
IUploadFileService uploadFileService,
IRepositoryWrapper repositoryWrapper,
IPageService pageService)
{
_uploadFileService = uploadFileService;
_repositoryWrapper = repositoryWrapper;
_pageService = pageService;
_siteSetting = snapshot.Value;
}
public async Task CreateSiteMapAsync() public async Task CreateSiteMapAsync()
{ {
XmlDocument doc = new XmlDocument(); XmlDocument doc = new XmlDocument();
@ -38,11 +30,11 @@ public class SiteMapService : ISiteMapService
doc.AppendChild(root); doc.AppendChild(root);
var productCategories = await _repositoryWrapper.SetRepository<ProductCategory>() var productCategories = await repositoryWrapper.SetRepository<ProductCategory>()
.TableNoTracking .TableNoTracking
.ToListAsync(); .ToListAsync();
var blogCategories= await _repositoryWrapper.SetRepository<BlogCategory>() var blogCategories= await repositoryWrapper.SetRepository<BlogCategory>()
.TableNoTracking .TableNoTracking
.ToListAsync(); .ToListAsync();
@ -96,7 +88,7 @@ public class SiteMapService : ISiteMapService
doc.WriteTo(writer); doc.WriteTo(writer);
writer.Flush(); writer.Flush();
byte[] byteArray = stream.ToArray(); byte[] byteArray = stream.ToArray();
await _uploadFileService.UploadFileByteAsync(new FileUploadRequest await uploadFileService.UploadFileByteAsync(new FileUploadRequest
{ {
FileBytes = byteArray, FileBytes = byteArray,
ContentType = "text/xml", ContentType = "text/xml",
@ -107,7 +99,7 @@ public class SiteMapService : ISiteMapService
await CreateCategoriesSiteMapsAsync(); await CreateCategoriesSiteMapsAsync();
await CreateProductsSiteMapsAsync(); await CreateProductsSiteMapsAsync();
await CreateBlogsSiteMapsAsync(); await CreateBlogsSiteMapsAsync();
//await CreateBrandsSiteMapsAsync(); await CreateBrandsSiteMapsAsync();
await CreateBlogCategoriesSiteMapsAsync(); await CreateBlogCategoriesSiteMapsAsync();
await CreatePagesSiteMapsAsync(); await CreatePagesSiteMapsAsync();
@ -118,7 +110,7 @@ public class SiteMapService : ISiteMapService
{ {
var siteMapsUId = SiteMapUIds.Pages; var siteMapsUId = SiteMapUIds.Pages;
var pages = await _pageService.GetPagesAsync(); var pages = await pageService.GetPagesAsync();
XmlDocument doc = new XmlDocument(); XmlDocument doc = new XmlDocument();
XmlDeclaration documentType = doc.CreateXmlDeclaration("1.0", "utf-8", null); XmlDeclaration documentType = doc.CreateXmlDeclaration("1.0", "utf-8", null);
@ -131,9 +123,12 @@ public class SiteMapService : ISiteMapService
root.SetAttribute("xmlns:image", "http://www.google.com/schemas/sitemap-image/1.1"); root.SetAttribute("xmlns:image", "http://www.google.com/schemas/sitemap-image/1.1");
doc.AppendChild(root); doc.AppendChild(root);
foreach (var page in pages) foreach (var page in pages.Where(p=>p.Indexing))
{ {
var productUrl = $"{_siteSetting.WebSiteUrl}/{page.Slug}"; string slugHtml = page.Slug;
if (slugHtml.Contains(' '))
slugHtml = WebUtility.UrlEncode(slugHtml.Replace(' ', '-'));
var productUrl = $"{_siteSetting.WebSiteUrl}/{slugHtml}";
XmlElement urlElement = doc.CreateElement("url", doc.DocumentElement?.NamespaceURI); XmlElement urlElement = doc.CreateElement("url", doc.DocumentElement?.NamespaceURI);
root.AppendChild(urlElement); root.AppendChild(urlElement);
@ -170,7 +165,7 @@ public class SiteMapService : ISiteMapService
zipStream.Close(); zipStream.Close();
var siteMapArray = compressedStream.ToArray(); var siteMapArray = compressedStream.ToArray();
await _uploadFileService.UploadFileByteAsync(new FileUploadRequest await uploadFileService.UploadFileByteAsync(new FileUploadRequest
{ {
FileBytes = siteMapArray, FileBytes = siteMapArray,
ContentType = "text/plain", ContentType = "text/plain",
@ -184,7 +179,7 @@ public class SiteMapService : ISiteMapService
{ {
var siteMapsUId = SiteMapUIds.Brands; var siteMapsUId = SiteMapUIds.Brands;
var brands = await _repositoryWrapper.SetRepository<Brand>() var brands = await repositoryWrapper.SetRepository<Brand>()
.TableNoTracking .TableNoTracking
.ToListAsync(); .ToListAsync();
@ -201,7 +196,10 @@ public class SiteMapService : ISiteMapService
foreach (var brand in brands) foreach (var brand in brands)
{ {
var productUrl = $"{_siteSetting.WebSiteUrl}/brands/{brand.Id}/{brand.Slug}"; string slugHtml = brand.Slug;
if (slugHtml.Contains(' '))
slugHtml = WebUtility.UrlEncode(slugHtml.Replace(' ', '-'));
var productUrl = $"{_siteSetting.WebSiteUrl}/brands/{brand.Id}/{slugHtml}";
XmlElement urlElement = doc.CreateElement("url", doc.DocumentElement?.NamespaceURI); XmlElement urlElement = doc.CreateElement("url", doc.DocumentElement?.NamespaceURI);
root.AppendChild(urlElement); root.AppendChild(urlElement);
@ -238,7 +236,7 @@ public class SiteMapService : ISiteMapService
zipStream.Close(); zipStream.Close();
var siteMapArray = compressedStream.ToArray(); var siteMapArray = compressedStream.ToArray();
await _uploadFileService.UploadFileByteAsync(new FileUploadRequest await uploadFileService.UploadFileByteAsync(new FileUploadRequest
{ {
FileBytes = siteMapArray, FileBytes = siteMapArray,
ContentType = "text/plain", ContentType = "text/plain",
@ -253,7 +251,7 @@ public class SiteMapService : ISiteMapService
{ {
var siteMapsUId = SiteMapUIds.Categories; var siteMapsUId = SiteMapUIds.Categories;
var categories = await _repositoryWrapper.SetRepository<ProductCategory>() var categories = await repositoryWrapper.SetRepository<ProductCategory>()
.TableNoTracking .TableNoTracking
.ToListAsync(); .ToListAsync();
@ -270,7 +268,10 @@ public class SiteMapService : ISiteMapService
foreach (var productCategory in categories) foreach (var productCategory in categories)
{ {
var productUrl = $"{_siteSetting.WebSiteUrl}/categories/{productCategory.Id}/{productCategory.Slug}"; string slugHtml = productCategory.Slug;
if (slugHtml.Contains(' '))
slugHtml = WebUtility.UrlEncode(slugHtml.Replace(' ', '-'));
var productUrl = $"{_siteSetting.WebSiteUrl}/categories/{productCategory.Id}/{slugHtml}";
XmlElement urlElement = doc.CreateElement("url", doc.DocumentElement?.NamespaceURI); XmlElement urlElement = doc.CreateElement("url", doc.DocumentElement?.NamespaceURI);
root.AppendChild(urlElement); root.AppendChild(urlElement);
@ -307,7 +308,7 @@ public class SiteMapService : ISiteMapService
zipStream.Close(); zipStream.Close();
var siteMapArray = compressedStream.ToArray(); var siteMapArray = compressedStream.ToArray();
await _uploadFileService.UploadFileByteAsync(new FileUploadRequest await uploadFileService.UploadFileByteAsync(new FileUploadRequest
{ {
FileBytes = siteMapArray, FileBytes = siteMapArray,
ContentType = "text/plain", ContentType = "text/plain",
@ -321,8 +322,9 @@ public class SiteMapService : ISiteMapService
private async Task CreateProductsSiteMapsAsync() private async Task CreateProductsSiteMapsAsync()
{ {
var products = await _repositoryWrapper.SetRepository<Product>() var products = await repositoryWrapper.SetRepository<Product>()
.TableNoTracking .TableNoTracking
.Where(p=>!p.IsSubProduct)
.Select(ProductMapper.ProjectToSDto) .Select(ProductMapper.ProjectToSDto)
.ToListAsync(); .ToListAsync();
@ -343,8 +345,10 @@ public class SiteMapService : ISiteMapService
foreach (var product in group) foreach (var product in group)
{ {
string slugHtml = product.Slug;
var productUrl = $"{_siteSetting.WebSiteUrl}/products/{product.Id}/{product.Slug}"; if (slugHtml.Contains(' '))
slugHtml = WebUtility.UrlEncode(slugHtml.Replace(' ', '-'));
var productUrl = $"{_siteSetting.WebSiteUrl}/products/{product.Id}/{slugHtml}";
XmlElement urlElement = doc.CreateElement("url", doc.DocumentElement?.NamespaceURI); XmlElement urlElement = doc.CreateElement("url", doc.DocumentElement?.NamespaceURI);
root.AppendChild(urlElement); root.AppendChild(urlElement);
@ -400,7 +404,7 @@ public class SiteMapService : ISiteMapService
zipStream.Close(); zipStream.Close();
var siteMapArray = compressedStream.ToArray(); var siteMapArray = compressedStream.ToArray();
await _uploadFileService.UploadFileByteAsync(new FileUploadRequest await uploadFileService.UploadFileByteAsync(new FileUploadRequest
{ {
FileBytes = siteMapArray, FileBytes = siteMapArray,
ContentType = "text/plain", ContentType = "text/plain",
@ -417,7 +421,7 @@ public class SiteMapService : ISiteMapService
private async Task CreateBlogsSiteMapsAsync() private async Task CreateBlogsSiteMapsAsync()
{ {
var blogs = await _repositoryWrapper.SetRepository<Blog>() var blogs = await repositoryWrapper.SetRepository<Blog>()
.TableNoTracking .TableNoTracking
.Select(BlogMapper.ProjectToSDto) .Select(BlogMapper.ProjectToSDto)
.ToListAsync(); .ToListAsync();
@ -444,7 +448,11 @@ public class SiteMapService : ISiteMapService
root.AppendChild(urlElement); root.AppendChild(urlElement);
XmlElement loc = doc.CreateElement("loc", doc.DocumentElement?.NamespaceURI); XmlElement loc = doc.CreateElement("loc", doc.DocumentElement?.NamespaceURI);
loc.InnerText = Path.Combine($"{_siteSetting.WebSiteUrl}/blogs/{blog.Id}/{blog.Slug}");
string slugHtml = blog.Slug;
if (slugHtml.Contains(' '))
slugHtml = WebUtility.UrlEncode(slugHtml.Replace(' ', '-'));
loc.InnerText = Path.Combine($"{_siteSetting.WebSiteUrl}/blogs/{blog.Id}/{slugHtml}");
urlElement.AppendChild(loc); urlElement.AppendChild(loc);
XmlElement lastmod = doc.CreateElement("lastmod", doc.DocumentElement?.NamespaceURI); XmlElement lastmod = doc.CreateElement("lastmod", doc.DocumentElement?.NamespaceURI);
@ -530,7 +538,7 @@ public class SiteMapService : ISiteMapService
zipStream.Close(); zipStream.Close();
var siteMapArray = compressedStream.ToArray(); var siteMapArray = compressedStream.ToArray();
await _uploadFileService.UploadFileByteAsync(new FileUploadRequest await uploadFileService.UploadFileByteAsync(new FileUploadRequest
{ {
FileBytes = siteMapArray, FileBytes = siteMapArray,
ContentType = "text/plain", ContentType = "text/plain",
@ -548,7 +556,7 @@ public class SiteMapService : ISiteMapService
{ {
var siteMapsUId = SiteMapUIds.BlogCategories; var siteMapsUId = SiteMapUIds.BlogCategories;
var blogCategories = await _repositoryWrapper.SetRepository<BlogCategory>() var blogCategories = await repositoryWrapper.SetRepository<BlogCategory>()
.TableNoTracking .TableNoTracking
.ToListAsync(); .ToListAsync();
@ -602,7 +610,7 @@ public class SiteMapService : ISiteMapService
zipStream.Close(); zipStream.Close();
var siteMapArray = compressedStream.ToArray(); var siteMapArray = compressedStream.ToArray();
await _uploadFileService.UploadFileByteAsync(new FileUploadRequest await uploadFileService.UploadFileByteAsync(new FileUploadRequest
{ {
FileBytes = siteMapArray, FileBytes = siteMapArray,
ContentType = "text/plain", ContentType = "text/plain",

View File

@ -8,6 +8,7 @@ public static class CoreConfig
public static async Task CoreInit(this IApplicationBuilder app) public static async Task CoreInit(this IApplicationBuilder app)
{ {
Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense("NjA1NkAzMjM2MkUzMTJFMzliSzVTQlJKN0NLVzNVOFVKSlErcVEzYW9PSkZ2dUhicHliVjkrMncxdHpRPQ==");
var scopeFactory = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>(); var scopeFactory = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>();
using (var scope = scopeFactory.CreateScope()) using (var scope = scopeFactory.CreateScope())
{ {

View File

@ -1,21 +1,17 @@
namespace Netina.Core.CoreServices.SearchServices; namespace Netina.Core.CoreServices.SearchServices;
public class GetEmallsProductsQueryHandler : IRequestHandler<GetEmallsProductsQuery, EmallsResponseDto> public class GetEmallsProductsQueryHandler(
IRepositoryWrapper repositoryWrapper,
IMediator mediator,
IOptionsSnapshot<SiteSettings> optionsSnapshot)
: IRequestHandler<GetEmallsProductsQuery, EmallsResponseDto>
{ {
private readonly IRepositoryWrapper _repositoryWrapper; private readonly SiteSettings _siteSetting = optionsSnapshot.Value;
private readonly IMediator _mediator;
private readonly SiteSettings _siteSetting;
public GetEmallsProductsQueryHandler(IRepositoryWrapper repositoryWrapper, IMediator mediator, IOptionsSnapshot<SiteSettings> optionsSnapshot)
{
_repositoryWrapper = repositoryWrapper;
_mediator = mediator;
_siteSetting = optionsSnapshot.Value;
}
public async Task<EmallsResponseDto> Handle(GetEmallsProductsQuery request, CancellationToken cancellationToken) public async Task<EmallsResponseDto> Handle(GetEmallsProductsQuery request, CancellationToken cancellationToken)
{ {
var page = request.Page; var page = request.Page;
var productsSDto = await _repositoryWrapper.SetRepository<Product>() var productsSDto = await repositoryWrapper.SetRepository<Product>()
.TableNoTracking .TableNoTracking
.OrderByDescending(p => p.ModifiedAt == DateTime.MinValue ? p.CreatedAt : p.ModifiedAt) .OrderByDescending(p => p.ModifiedAt == DateTime.MinValue ? p.CreatedAt : p.ModifiedAt)
.Select(p => new ProductSDto .Select(p => new ProductSDto
@ -37,7 +33,7 @@ public class GetEmallsProductsQueryHandler : IRequestHandler<GetEmallsProductsQu
foreach (var productSDto in productsSDto) foreach (var productSDto in productsSDto)
await _mediator.Send(new CalculateProductDiscountCommand(productSDto), cancellationToken); await mediator.Send(new CalculateProductDiscountCommand(productSDto), cancellationToken);
var products = new List<EmallsProductResponseDto>(); var products = new List<EmallsProductResponseDto>();
foreach (var product in productsSDto) foreach (var product in productsSDto)
{ {
@ -51,18 +47,18 @@ public class GetEmallsProductsQueryHandler : IRequestHandler<GetEmallsProductsQu
}; };
if (product.Cost > product.CostWithDiscount) if (product.Cost > product.CostWithDiscount)
{ {
torobProduct.old_price = (int)product.Cost; torobProduct.old_price = (int)product.Cost / 10;
torobProduct.price = (int)product.CostWithDiscount; torobProduct.price = (int)product.CostWithDiscount / 10;
} }
else else
torobProduct.price = (int)product.Cost; torobProduct.price = (int)product.Cost / 10;
products.Add(torobProduct); products.Add(torobProduct);
} }
var response = new EmallsResponseDto(); var response = new EmallsResponseDto();
response.item_per_page = request.Count; response.item_per_page = request.Count;
response.page_num = request.Page; response.page_num = request.Page;
response.total_items = (await _repositoryWrapper.SetRepository<Product>().TableNoTracking.CountAsync(cancellationToken)); response.total_items = (await repositoryWrapper.SetRepository<Product>().TableNoTracking.CountAsync(cancellationToken));
response.pages_count = response.total_items / request.Count; response.pages_count = response.total_items / request.Count;
response.products = products; response.products = products;

View File

@ -2,27 +2,22 @@
namespace Netina.Core.CoreServices.SearchServices; namespace Netina.Core.CoreServices.SearchServices;
public class GetThumbSearchProductsQueryHandler : IRequestHandler<GetThumbSearchProductsQuery, SearchResponseDto> public class GetThumbSearchProductsQueryHandler(IRepositoryWrapper repositoryWrapper)
: IRequestHandler<GetThumbSearchProductsQuery, SearchResponseDto>
{ {
private readonly IRepositoryWrapper _repositoryWrapper;
public GetThumbSearchProductsQueryHandler(IRepositoryWrapper repositoryWrapper)
{
_repositoryWrapper = repositoryWrapper;
}
public async Task<SearchResponseDto> Handle(GetThumbSearchProductsQuery request, CancellationToken cancellationToken) public async Task<SearchResponseDto> Handle(GetThumbSearchProductsQuery request, CancellationToken cancellationToken)
{ {
var searchQuery = request.Name; var searchQuery = request.Name;
var products = await _repositoryWrapper.SetRepository<Product>() var products = await repositoryWrapper.SetRepository<Product>()
.TableNoTracking .TableNoTracking
.OrderByDescending(p => EF.Functions.TrigramsSimilarity(p.PersianName, searchQuery)) .OrderByDescending(p => EF.Functions.TrigramsSimilarity(p.PersianName, searchQuery))
.Take(8) .Take(8)
.Select(ProductMapper.ProjectToSDto) .Select(ProductMapper.ProjectToSDto)
.ToListAsync(cancellationToken); .ToListAsync(cancellationToken);
var categories = await _repositoryWrapper.SetRepository<ProductCategory>() var categories = await repositoryWrapper.SetRepository<ProductCategory>()
.TableNoTracking .TableNoTracking
.OrderByDescending(p => EF.Functions.TrigramsSimilarity(p.Name.ToLower().Trim(), searchQuery)) .OrderByDescending(p => EF.Functions.TrigramsSimilarity(p.Name.ToLower().Trim(), searchQuery))
.Take(8) .Take(8)

View File

@ -1,21 +1,17 @@
namespace Netina.Core.CoreServices.SearchServices; namespace Netina.Core.CoreServices.SearchServices;
public class GetTorobProductsQueryHandler : IRequestHandler<GetTorobProductsQuery, List<TorobProductResponseDto>> public class GetTorobProductsQueryHandler(
IRepositoryWrapper repositoryWrapper,
IMediator mediator,
IOptionsSnapshot<SiteSettings> optionsSnapshot)
: IRequestHandler<GetTorobProductsQuery, List<TorobProductResponseDto>>
{ {
private readonly IRepositoryWrapper _repositoryWrapper; private readonly SiteSettings _siteSetting = optionsSnapshot.Value;
private readonly IMediator _mediator;
private readonly SiteSettings _siteSetting;
public GetTorobProductsQueryHandler(IRepositoryWrapper repositoryWrapper, IMediator mediator, IOptionsSnapshot<SiteSettings> optionsSnapshot)
{
_repositoryWrapper = repositoryWrapper;
_mediator = mediator;
_siteSetting = optionsSnapshot.Value;
}
public async Task<List<TorobProductResponseDto>> Handle(GetTorobProductsQuery request, CancellationToken cancellationToken) public async Task<List<TorobProductResponseDto>> Handle(GetTorobProductsQuery request, CancellationToken cancellationToken)
{ {
int page = request.Page == 0 ? 1 : request.Page; int page = request.Page == 0 ? 1 : request.Page;
var productsSDto = await _repositoryWrapper.SetRepository<Product>() var productsSDto = await repositoryWrapper.SetRepository<Product>()
.TableNoTracking .TableNoTracking
.OrderByDescending(p => p.ModifiedAt == DateTime.MinValue ? p.CreatedAt : p.ModifiedAt) .OrderByDescending(p => p.ModifiedAt == DateTime.MinValue ? p.CreatedAt : p.ModifiedAt)
.Select(p => new ProductSDto .Select(p => new ProductSDto
@ -37,7 +33,7 @@ public class GetTorobProductsQueryHandler : IRequestHandler<GetTorobProductsQuer
foreach (var productSDto in productsSDto) foreach (var productSDto in productsSDto)
await _mediator.Send(new CalculateProductDiscountCommand(productSDto), cancellationToken); await mediator.Send(new CalculateProductDiscountCommand(productSDto), cancellationToken);
var products = new List<TorobProductResponseDto>(); var products = new List<TorobProductResponseDto>();
foreach (var product in productsSDto) foreach (var product in productsSDto)
{ {
@ -49,11 +45,11 @@ public class GetTorobProductsQueryHandler : IRequestHandler<GetTorobProductsQuer
}; };
if (product.Cost > product.CostWithDiscount) if (product.Cost > product.CostWithDiscount)
{ {
torobProduct.old_price = product.Cost; torobProduct.old_price = product.Cost / 10;
torobProduct.price = product.CostWithDiscount; torobProduct.price = product.CostWithDiscount / 10;
} }
else else
torobProduct.price = product.Cost; torobProduct.price = product.Cost / 10;
products.Add(torobProduct); products.Add(torobProduct);
} }

View File

@ -2,22 +2,17 @@
namespace Netina.Core.CoreServices.WebSiteServices; namespace Netina.Core.CoreServices.WebSiteServices;
public class GetWebSiteNavBarCommandHandler : IRequestHandler<GetWebSiteNavBarCommand , List<NavMenuItem>> public class GetWebSiteNavBarCommandHandler(
IRepositoryWrapper repositoryWrapper,
ISettingService settingService,
IOptionsSnapshot<SiteSettings> optionsSnapshot)
: IRequestHandler<GetWebSiteNavBarCommand, List<NavMenuItem>>
{ {
private readonly IRepositoryWrapper _repositoryWrapper; private readonly SiteSettings _siteSetting = optionsSnapshot.Value;
private readonly ISettingService _settingService;
private readonly SiteSettings _siteSetting;
public GetWebSiteNavBarCommandHandler(IRepositoryWrapper repositoryWrapper , ISettingService settingService,IOptionsSnapshot<SiteSettings> optionsSnapshot)
{
_repositoryWrapper = repositoryWrapper;
_settingService = settingService;
_siteSetting = optionsSnapshot.Value;
}
public async Task<List<NavMenuItem>> Handle(GetWebSiteNavBarCommand request, CancellationToken cancellationToken) public async Task<List<NavMenuItem>> Handle(GetWebSiteNavBarCommand request, CancellationToken cancellationToken)
{ {
var navBarSetting = await _settingService.GetSettingAsync(nameof(NavMenuSetting), cancellationToken) as NavMenuSetting; var navBarSetting = await settingService.GetSettingAsync(nameof(NavMenuSetting), cancellationToken) as NavMenuSetting;
var navBarItems = new List<NavMenuItem>(); var navBarItems = new List<NavMenuItem>();
if (navBarSetting == null) if (navBarSetting == null)
return new List<NavMenuItem>(); return new List<NavMenuItem>();
@ -30,7 +25,7 @@ public class GetWebSiteNavBarCommandHandler : IRequestHandler<GetWebSiteNavBarCo
if (navBarSetting.ShowBlogCategories) if (navBarSetting.ShowBlogCategories)
{ {
var baseCategories = await _repositoryWrapper.SetRepository<BlogCategory>() var baseCategories = await repositoryWrapper.SetRepository<BlogCategory>()
.TableNoTracking .TableNoTracking
.OrderByDescending(c => c.CreatedAt) .OrderByDescending(c => c.CreatedAt)
.Select(BlogCategoryMapper.ProjectToSDto) .Select(BlogCategoryMapper.ProjectToSDto)
@ -54,7 +49,7 @@ public class GetWebSiteNavBarCommandHandler : IRequestHandler<GetWebSiteNavBarCo
} }
else if (navBarSetting.ShowProductCategories) else if (navBarSetting.ShowProductCategories)
{ {
var baseCategories = await _repositoryWrapper.SetRepository<ProductCategory>() var baseCategories = await repositoryWrapper.SetRepository<ProductCategory>()
.TableNoTracking .TableNoTracking
.OrderByDescending(c => c.CreatedAt) .OrderByDescending(c => c.CreatedAt)
.Select(ProductCategoryMapper.ProjectToSDto) .Select(ProductCategoryMapper.ProjectToSDto)

View File

@ -0,0 +1,36 @@
using Netina.Domain.Entities.Comments;
namespace Netina.Core.EntityServices.CommentHandlers;
public class ConfirmCommentCommandHandler(IRepositoryWrapper repositoryWrapper)
: IRequestHandler<ConfirmCommentCommand, Guid>
{
public async Task<Guid> Handle(ConfirmCommentCommand request, CancellationToken cancellationToken)
{
var review = await repositoryWrapper.SetRepository<Comment>().TableNoTracking
.FirstOrDefaultAsync(r => r.Id == request.Id, cancellationToken);
if (review == null)
throw new AppException("Comment not found", ApiResultStatusCode.NotFound);
review.ConfirmReview();
var productComment = await repositoryWrapper.SetRepository<ProductComment>()
.TableNoTracking.FirstOrDefaultAsync(f => f.Id == request.Id, cancellationToken);
if (productComment != null)
{
var product = await repositoryWrapper.SetRepository<Product>()
.TableNoTracking
.FirstOrDefaultAsync(p => p.Id == productComment.ProductId, cancellationToken);
if (product == null)
throw new AppException("Product not found", ApiResultStatusCode.NotFound);
product.AddRate(productComment.Rate);
repositoryWrapper.SetRepository<Product>().Update(product);
await repositoryWrapper.SaveChangesAsync(cancellationToken);
}
repositoryWrapper.SetRepository<Comment>().Update(review);
await repositoryWrapper.SaveChangesAsync(cancellationToken);
return review.Id;
}
}

View File

@ -1,43 +1,37 @@
namespace Netina.Core.EntityServices.DiscountHandlers; using Netina.Domain.Entities.ProductCategories;
public class CalculateOrderDiscountCommandHandler : IRequestHandler<CalculateOrderDiscountCommand , double> namespace Netina.Core.EntityServices.DiscountHandlers;
public class CalculateOrderDiscountCommandHandler(
IRepositoryWrapper repositoryWrapper,
ICurrentUserService currentUserService)
: IRequestHandler<CalculateOrderDiscountCommand, double>
{ {
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly ICurrentUserService _currentUserService;
public CalculateOrderDiscountCommandHandler(IRepositoryWrapper repositoryWrapper,ICurrentUserService currentUserService)
{
_repositoryWrapper = repositoryWrapper;
_currentUserService = currentUserService;
}
public async Task<double> Handle(CalculateOrderDiscountCommand request, CancellationToken cancellationToken) public async Task<double> Handle(CalculateOrderDiscountCommand request, CancellationToken cancellationToken)
{ {
if (request.Order == null) if (request.Order == null)
throw new AppException("Order is null", ApiResultStatusCode.BadRequest); throw new AppException("Order is null", ApiResultStatusCode.BadRequest);
var discount = await _repositoryWrapper.SetRepository<Discount>() var discount = await repositoryWrapper.SetRepository<Discount>()
.TableNoTracking .TableNoTracking
.FirstOrDefaultAsync(d => d.Code == request.DiscountCode, cancellationToken); .FirstOrDefaultAsync(d => d.Code == request.DiscountCode, cancellationToken);
if (discount == null) if (discount == null)
throw new AppException("تخفیف وجود منقضی شده است یا وجود ندارد", ApiResultStatusCode.NotFound); throw new AppException("تخفیف وجود منقضی شده است یا وجود ندارد", ApiResultStatusCode.NotFound);
if (_currentUserService.UserId != null && Guid.TryParse(_currentUserService.UserId, out Guid userId))
{
var discountedUserOrder = await _repositoryWrapper.SetRepository<Order>()
.TableNoTracking
.FirstOrDefaultAsync(f => f.CustomerId == userId && f.DiscountCode == discount.Code, cancellationToken);
if (discountedUserOrder != null)
throw new AppException("شما یک بار از این کد تخفیف استفاده کرده اید", ApiResultStatusCode.BadRequest);
}
if (discount.IsForFirstPurchase) if (discount.IsForFirstPurchase)
{ {
if (_currentUserService.UserId != null && Guid.TryParse(_currentUserService.UserId, out Guid firstPurchaseUserId)) if (currentUserService.UserId != null && Guid.TryParse(currentUserService.UserId, out Guid firstPurchaseUserId))
{ {
var userOrderCount = await _repositoryWrapper.SetRepository<Order>() var customer = await repositoryWrapper.SetRepository<Customer>()
.TableNoTracking .TableNoTracking
.CountAsync(f => f.CustomerId == firstPurchaseUserId && f.DiscountCode == discount.Code, cancellationToken); .FirstOrDefaultAsync(c => c.UserId == firstPurchaseUserId, cancellationToken);
if (customer == null)
throw new BaseApiException(ApiResultStatusCode.NotFound, "Customer not found");
var userOrderCount = await repositoryWrapper.SetRepository<Order>()
.TableNoTracking
.CountAsync(f => f.CustomerId == customer.Id && f.DiscountCode == discount.Code, cancellationToken);
if (userOrderCount > 0) if (userOrderCount > 0)
throw new AppException("شما قبلا خریدی داشته اید و نمیتوانید از تخفیف اولین خرید استفاده کنید", ApiResultStatusCode.BadRequest); throw new AppException("شما قبلا خریدی داشته اید و نمیتوانید از تخفیف اولین خرید استفاده کنید", ApiResultStatusCode.BadRequest);
} }
@ -54,18 +48,22 @@ public class CalculateOrderDiscountCommandHandler : IRequestHandler<CalculateOrd
} }
else if (discount.Type == DiscountType.Category) else if (discount.Type == DiscountType.Category)
{ {
var categoryDiscount = await _repositoryWrapper.SetRepository<CategoryDiscount>() var categoryDiscount = await repositoryWrapper.SetRepository<CategoryDiscount>()
.TableNoTracking .TableNoTracking
.FirstOrDefaultAsync(d => d.Code == request.DiscountCode, cancellationToken); .FirstOrDefaultAsync(d => d.Code == request.DiscountCode, cancellationToken);
if ( categoryDiscount!=null && !categoryDiscount.IsExpired()) if ( categoryDiscount!=null && !categoryDiscount.IsExpired())
{ {
totalPrice = request.Order.OrderProducts.Where(op => op.ProductCategoryId == categoryDiscount.CategoryId).Sum(op => op.ProductCost); var subCats = await repositoryWrapper.SetRepository<ProductCategory>().TableNoTracking
.Where(c => c.ParentId == categoryDiscount.CategoryId)
.Select(c => c.Id)
.ToListAsync(cancellationToken);
subCats.Add(categoryDiscount.CategoryId);
totalPrice = request.Order.OrderProducts.Where(op => subCats.Contains(op.ProductCategoryId)).Sum(op => op.ProductCost);
} }
} }
else if (discount.Type == DiscountType.Product) else if (discount.Type == DiscountType.Product)
{ {
var productDiscount = await _repositoryWrapper.SetRepository<ProductDiscount>() var productDiscount = await repositoryWrapper.SetRepository<ProductDiscount>()
.TableNoTracking .TableNoTracking
.FirstOrDefaultAsync(d => d.Code == request.DiscountCode, cancellationToken); .FirstOrDefaultAsync(d => d.Code == request.DiscountCode, cancellationToken);
@ -75,6 +73,18 @@ public class CalculateOrderDiscountCommandHandler : IRequestHandler<CalculateOrd
} }
} }
else if (discount.Type == DiscountType.Brand)
{
var brandDiscount = await repositoryWrapper.SetRepository<BrandDiscount>()
.TableNoTracking
.FirstOrDefaultAsync(d => d.Code == request.DiscountCode, cancellationToken);
if (brandDiscount != null && !brandDiscount.IsExpired())
{
totalPrice = request.Order.OrderProducts.Where(op => op.BrandId == brandDiscount.BrandId).Sum(op => op.ProductCost);
}
}
else if (discount.Type == DiscountType.Subscriber) else if (discount.Type == DiscountType.Subscriber)
{ {
throw new NotImplementedException("Subscribe discount not implemented"); throw new NotImplementedException("Subscribe discount not implemented");

View File

@ -1,15 +1,8 @@
namespace Netina.Core.EntityServices.DiscountHandlers; namespace Netina.Core.EntityServices.DiscountHandlers;
public class CalculateProductDiscountCommandHandler : IRequestHandler<CalculateProductDiscountCommand, bool> public class CalculateProductDiscountCommandHandler(IRepositoryWrapper repositoryWrapper)
: IRequestHandler<CalculateProductDiscountCommand, bool>
{ {
private readonly IRepositoryWrapper _repositoryWrapper;
public CalculateProductDiscountCommandHandler(IRepositoryWrapper repositoryWrapper)
{
_repositoryWrapper = repositoryWrapper;
}
public async Task<bool> Handle(CalculateProductDiscountCommand request, CancellationToken cancellationToken) public async Task<bool> Handle(CalculateProductDiscountCommand request, CancellationToken cancellationToken)
{ {
if (request.Product is ProductSDto product) if (request.Product is ProductSDto product)
@ -30,7 +23,7 @@ public class CalculateProductDiscountCommandHandler : IRequestHandler<CalculateP
request.CostWithDiscount = request.Cost; request.CostWithDiscount = request.Cost;
double totalPrice = request.Cost; double totalPrice = request.Cost;
var allDiscount = await _repositoryWrapper.SetRepository<Discount>() var allDiscount = await repositoryWrapper.SetRepository<Discount>()
.TableNoTracking .TableNoTracking
.FirstOrDefaultAsync(d => d.Type == DiscountType.All && d.HasCode == false && d.ExpireDate.Date >= DateTime.Today.Date, cancellationToken); .FirstOrDefaultAsync(d => d.Type == DiscountType.All && d.HasCode == false && d.ExpireDate.Date >= DateTime.Today.Date, cancellationToken);
@ -42,7 +35,7 @@ public class CalculateProductDiscountCommandHandler : IRequestHandler<CalculateP
request.HasDiscount = true; request.HasDiscount = true;
} }
var categoryDiscount = await _repositoryWrapper.SetRepository<CategoryDiscount>() var categoryDiscount = await repositoryWrapper.SetRepository<CategoryDiscount>()
.TableNoTracking .TableNoTracking
.FirstOrDefaultAsync(d => d.CategoryId == request.CategoryId && d.HasCode == false && d.ExpireDate.Date >= DateTime.Today.Date, cancellationToken); .FirstOrDefaultAsync(d => d.CategoryId == request.CategoryId && d.HasCode == false && d.ExpireDate.Date >= DateTime.Today.Date, cancellationToken);
@ -53,7 +46,7 @@ public class CalculateProductDiscountCommandHandler : IRequestHandler<CalculateP
request.HasDiscount = true; request.HasDiscount = true;
} }
var productDiscount = await _repositoryWrapper.SetRepository<ProductDiscount>() var productDiscount = await repositoryWrapper.SetRepository<ProductDiscount>()
.TableNoTracking .TableNoTracking
.Where(d => d.HasCode == false && d.ProductId == request.Id && d.ExpireDate.Date >= DateTime.Today.Date) .Where(d => d.HasCode == false && d.ProductId == request.Id && d.ExpireDate.Date >= DateTime.Today.Date)
.OrderByDescending(d => d.CreatedAt) .OrderByDescending(d => d.CreatedAt)
@ -75,6 +68,12 @@ public class CalculateProductDiscountCommandHandler : IRequestHandler<CalculateP
request.DiscountPercent = request.Cost == 0 ? 0 : 100 - 100 * request.CostWithDiscount / request.Cost; request.DiscountPercent = request.Cost == 0 ? 0 : 100 - 100 * request.CostWithDiscount / request.Cost;
} }
if (request.DiscountPercent == 0)
{
request.CostWithDiscount = request.Cost;
request.HasDiscount = false;
}
return request; return request;
} }
@ -85,7 +84,7 @@ public class CalculateProductDiscountCommandHandler : IRequestHandler<CalculateP
request.CostWithDiscount = request.Cost; request.CostWithDiscount = request.Cost;
double totalPrice = request.Cost; double totalPrice = request.Cost;
var allDiscount = await _repositoryWrapper.SetRepository<Discount>() var allDiscount = await repositoryWrapper.SetRepository<Discount>()
.TableNoTracking .TableNoTracking
.FirstOrDefaultAsync(d => d.Type == DiscountType.All && d.HasCode == false && d.ExpireDate.Date >= DateTime.Today.Date, cancellationToken); .FirstOrDefaultAsync(d => d.Type == DiscountType.All && d.HasCode == false && d.ExpireDate.Date >= DateTime.Today.Date, cancellationToken);
@ -97,7 +96,7 @@ public class CalculateProductDiscountCommandHandler : IRequestHandler<CalculateP
request.HasDiscount = true; request.HasDiscount = true;
} }
var categoryDiscount = await _repositoryWrapper.SetRepository<CategoryDiscount>() var categoryDiscount = await repositoryWrapper.SetRepository<CategoryDiscount>()
.TableNoTracking .TableNoTracking
.FirstOrDefaultAsync(d => d.CategoryId == request.CategoryId && d.HasCode == false && d.ExpireDate.Date >= DateTime.Today.Date, cancellationToken); .FirstOrDefaultAsync(d => d.CategoryId == request.CategoryId && d.HasCode == false && d.ExpireDate.Date >= DateTime.Today.Date, cancellationToken);
@ -108,7 +107,7 @@ public class CalculateProductDiscountCommandHandler : IRequestHandler<CalculateP
request.HasDiscount = true; request.HasDiscount = true;
} }
var productDiscount = await _repositoryWrapper.SetRepository<ProductDiscount>() var productDiscount = await repositoryWrapper.SetRepository<ProductDiscount>()
.TableNoTracking .TableNoTracking
.Where(d => d.HasCode == false && d.ProductId == request.Id && d.ExpireDate.Date >= DateTime.Today.Date) .Where(d => d.HasCode == false && d.ProductId == request.Id && d.ExpireDate.Date >= DateTime.Today.Date)
.OrderByDescending(d => d.CreatedAt) .OrderByDescending(d => d.CreatedAt)
@ -132,6 +131,12 @@ public class CalculateProductDiscountCommandHandler : IRequestHandler<CalculateP
request.CostWithDiscount = discountPrice; request.CostWithDiscount = discountPrice;
request.DiscountPercent = request.Cost == 0 ? 0 : 100 - 100 * request.CostWithDiscount / request.Cost; request.DiscountPercent = request.Cost == 0 ? 0 : 100 - 100 * request.CostWithDiscount / request.Cost;
} }
if (request.DiscountPercent == 0)
{
request.CostWithDiscount = request.Cost;
request.HasDiscount = false;
}
return request; return request;
} }

View File

@ -0,0 +1,30 @@
namespace Netina.Core.EntityServices.DiscountHandlers;
public class CheckUserDiscountFirstUseCommandHandler(
IRepositoryWrapper repositoryWrapper,
ICurrentUserService currentUserService)
: IRequestHandler<CheckUserDiscountFirstUseCommand, bool>
{
public async Task<bool> Handle(CheckUserDiscountFirstUseCommand request, CancellationToken cancellationToken)
{
if (currentUserService.UserId != null && Guid.TryParse(currentUserService.UserId, out Guid userId))
{
var customer = await repositoryWrapper.SetRepository<Customer>()
.TableNoTracking
.FirstOrDefaultAsync(c => c.UserId == userId, cancellationToken);
if (customer == null)
throw new BaseApiException(ApiResultStatusCode.NotFound, "Customer not found");
var discountedUserOrder = await repositoryWrapper.SetRepository<Order>()
.TableNoTracking
.FirstOrDefaultAsync(f => f.CustomerId == customer.Id && f.DiscountCode == request.DiscountCode,
cancellationToken);
if (discountedUserOrder != null)
return false;
return true;
}
else
throw new BaseApiException(ApiResultStatusCode.BadRequest,"UserId is wrong");
}
}

View File

@ -1,48 +1,38 @@
namespace Netina.Core.EntityServices.MarketerHandlers; namespace Netina.Core.EntityServices.MarketerHandlers;
public class CreateMarketerDiscountCommandHandler : IRequestHandler<CreateMarketerDiscountCommand, string> public class CreateMarketerDiscountCommandHandler(
UserManager<ApplicationUser> userManager,
IRepositoryWrapper repositoryWrapper,
ICurrentUserService currentUserService,
ISettingService settingService)
: IRequestHandler<CreateMarketerDiscountCommand, string>
{ {
private readonly UserManager<ApplicationUser> _userManager;
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly ICurrentUserService _currentUserService;
private readonly ISettingService _settingService;
public CreateMarketerDiscountCommandHandler(UserManager<ApplicationUser> userManager,
IRepositoryWrapper repositoryWrapper,
ICurrentUserService currentUserService,
ISettingService settingService)
{
_userManager = userManager;
_repositoryWrapper = repositoryWrapper;
_currentUserService = currentUserService;
_settingService = settingService;
}
public async Task<string> Handle(CreateMarketerDiscountCommand request, CancellationToken cancellationToken) public async Task<string> Handle(CreateMarketerDiscountCommand request, CancellationToken cancellationToken)
{ {
var userId = request.MarketerUserId; var userId = request.MarketerUserId;
if (userId == default) if (userId == default)
{ {
if (_currentUserService.UserId == null) if (currentUserService.UserId == null)
throw new AppException("User id is null"); throw new AppException("User id is null");
if (!Guid.TryParse(_currentUserService.UserId, out userId)) if (!Guid.TryParse(currentUserService.UserId, out userId))
throw new AppException("User id is wrong"); throw new AppException("User id is wrong");
} }
var user = await _userManager.FindByIdAsync(userId.ToString()); var user = await userManager.FindByIdAsync(userId.ToString());
if (user == null) if (user == null)
throw new AppException("User not found", ApiResultStatusCode.NotFound); throw new AppException("User not found", ApiResultStatusCode.NotFound);
var marketer = await _repositoryWrapper.SetRepository<Marketer>() var marketer = await repositoryWrapper.SetRepository<Marketer>()
.TableNoTracking .TableNoTracking
.FirstOrDefaultAsync(m => m.UserId == user.Id, cancellationToken); .FirstOrDefaultAsync(m => m.UserId == user.Id, cancellationToken);
if (marketer == null) if (marketer == null)
throw new AppException("Marketer not found", ApiResultStatusCode.NotFound); throw new AppException("Marketer not found", ApiResultStatusCode.NotFound);
var foundedDiscount = await _repositoryWrapper.SetRepository<Discount>() var foundedDiscount = await repositoryWrapper.SetRepository<Discount>()
.TableNoTracking .TableNoTracking
.FirstOrDefaultAsync(d => d.IsForSaleCooperation && d.MarketerId == marketer.Id, cancellationToken); .FirstOrDefaultAsync(d => d.IsForSaleCooperation && d.MarketerId == marketer.Id, cancellationToken);
if (foundedDiscount == null) if (foundedDiscount == null)
{ {
var setting = await _settingService.GetSettingAsync(nameof(MarketerSetting), cancellationToken); var setting = await settingService.GetSettingAsync(nameof(MarketerSetting), cancellationToken);
int discountPercent = 10; int discountPercent = 10;
if (setting is MarketerSetting marketerSetting) if (setting is MarketerSetting marketerSetting)
discountPercent = marketerSetting.DiscountPercent; discountPercent = marketerSetting.DiscountPercent;
@ -53,8 +43,8 @@ public class CreateMarketerDiscountCommandHandler : IRequestHandler<CreateMarket
false, 0, false, true, 0, false, false, false); false, 0, false, true, 0, false, false, false);
foundedDiscount.SetCorporate(marketer.Id); foundedDiscount.SetCorporate(marketer.Id);
_repositoryWrapper.SetRepository<Discount>().Add(foundedDiscount); repositoryWrapper.SetRepository<Discount>().Add(foundedDiscount);
await _repositoryWrapper.SaveChangesAsync(cancellationToken); await repositoryWrapper.SaveChangesAsync(cancellationToken);
return foundedDiscount.Code; return foundedDiscount.Code;
} }

View File

@ -2,18 +2,12 @@
namespace Netina.Core.EntityServices.MarketerHandlers; namespace Netina.Core.EntityServices.MarketerHandlers;
public class GetMarketerProfileQueryHandler : IRequestHandler<GetMarketerProfileQuery, MarketerProfileResponseDto> public class GetMarketerProfileQueryHandler(
IRepositoryWrapper repositoryWrapper,
ICurrentUserService currentUserService,
ISettingService settingService)
: IRequestHandler<GetMarketerProfileQuery, MarketerProfileResponseDto>
{ {
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly ICurrentUserService _currentUserService;
private readonly ISettingService _settingService;
public GetMarketerProfileQueryHandler(IRepositoryWrapper repositoryWrapper, ICurrentUserService currentUserService,ISettingService settingService)
{
_repositoryWrapper = repositoryWrapper;
_currentUserService = currentUserService;
_settingService = settingService;
}
public async Task<MarketerProfileResponseDto> Handle(GetMarketerProfileQuery request, CancellationToken cancellationToken) public async Task<MarketerProfileResponseDto> Handle(GetMarketerProfileQuery request, CancellationToken cancellationToken)
{ {
Guid marketerId; Guid marketerId;
@ -21,17 +15,17 @@ public class GetMarketerProfileQueryHandler : IRequestHandler<GetMarketerProfile
if (request.MarketerId != null) if (request.MarketerId != null)
{ {
marketerId = request.MarketerId.Value; marketerId = request.MarketerId.Value;
marketer = await _repositoryWrapper.SetRepository<Marketer>() marketer = await repositoryWrapper.SetRepository<Marketer>()
.TableNoTracking .TableNoTracking
.FirstOrDefaultAsync(m => m.Id == marketerId, cancellationToken); .FirstOrDefaultAsync(m => m.Id == marketerId, cancellationToken);
} }
else else
{ {
if (_currentUserService.UserId == null) if (currentUserService.UserId == null)
throw new BaseApiException("User id is null"); throw new BaseApiException("User id is null");
if (!Guid.TryParse(_currentUserService.UserId, out Guid userId)) if (!Guid.TryParse(currentUserService.UserId, out Guid userId))
throw new BaseApiException("User id is wrong"); throw new BaseApiException("User id is wrong");
marketer = await _repositoryWrapper.SetRepository<Marketer>() marketer = await repositoryWrapper.SetRepository<Marketer>()
.TableNoTracking .TableNoTracking
.FirstOrDefaultAsync(m => m.UserId == userId, cancellationToken); .FirstOrDefaultAsync(m => m.UserId == userId, cancellationToken);
@ -40,26 +34,26 @@ public class GetMarketerProfileQueryHandler : IRequestHandler<GetMarketerProfile
if (marketer == null) if (marketer == null)
throw new BaseApiException(ApiResultStatusCode.MarketerNotFound,"Marketer not found" ,HttpStatusCode.NotFound); throw new BaseApiException(ApiResultStatusCode.MarketerNotFound,"Marketer not found" ,HttpStatusCode.NotFound);
var discount = await _repositoryWrapper.SetRepository<Discount>() var discount = await repositoryWrapper.SetRepository<Discount>()
.TableNoTracking .TableNoTracking
.FirstOrDefaultAsync(d => d.MarketerId == marketer.Id, cancellationToken); .FirstOrDefaultAsync(d => d.MarketerId == marketer.Id, cancellationToken);
if (discount == null) if (discount == null)
throw new BaseApiException("Marketer has no discount"); throw new BaseApiException("Marketer has no discount");
var setting = (await _settingService.GetSettingAsync(nameof(MarketerSetting), cancellationToken)) as MarketerSetting; var setting = (await settingService.GetSettingAsync(nameof(MarketerSetting), cancellationToken)) as MarketerSetting;
if (setting == null) if (setting == null)
throw new BaseApiException("MarketerSetting is null"); throw new BaseApiException("MarketerSetting is null");
var response = new MarketerProfileResponseDto(); var response = new MarketerProfileResponseDto();
var orderCount = await _repositoryWrapper.SetRepository<Order>() var orderCount = await repositoryWrapper.SetRepository<Order>()
.TableNoTracking .TableNoTracking
.CountAsync(o => o.DiscountCode == discount.Code, cancellationToken); .CountAsync(o => o.DiscountCode == discount.Code, cancellationToken);
response.OrderCount = orderCount; response.OrderCount = orderCount;
var newTotalProductPrice = await _repositoryWrapper.SetRepository<Order>() var newTotalProductPrice = await repositoryWrapper.SetRepository<Order>()
.TableNoTracking .TableNoTracking
.Where(o => o.DiscountCode == discount.Code && o.OrderAt.Date > marketer.LastSettlement.Date) .Where(o => o.DiscountCode == discount.Code && o.OrderAt.Date > marketer.LastSettlement.Date)
.SumAsync(o => o.TotalProductsPrice, cancellationToken); .SumAsync(o => o.TotalProductsPrice, cancellationToken);

View File

@ -1,36 +1,29 @@
namespace Netina.Core.EntityServices.MarketerHandlers; namespace Netina.Core.EntityServices.MarketerHandlers;
public class SignUpMarketerCommandHandler : IRequestHandler<SignUpMarketerCommand,MarketerProfileResponseDto> public class SignUpMarketerCommandHandler(
UserManager<ApplicationUser> userManager,
IMediator mediator,
ICurrentUserService currentUserService,
IRepositoryWrapper repositoryWrapper)
: IRequestHandler<SignUpMarketerCommand, MarketerProfileResponseDto>
{ {
private readonly UserManager<ApplicationUser> _userManager;
private readonly IMediator _mediator;
private readonly ICurrentUserService _currentUserService;
private readonly IRepositoryWrapper _repositoryWrapper;
public SignUpMarketerCommandHandler(UserManager<ApplicationUser> userManager,IMediator mediator,ICurrentUserService currentUserService,IRepositoryWrapper repositoryWrapper)
{
_userManager = userManager;
_mediator = mediator;
_currentUserService = currentUserService;
_repositoryWrapper = repositoryWrapper;
}
public async Task<MarketerProfileResponseDto> Handle(SignUpMarketerCommand request, CancellationToken cancellationToken) public async Task<MarketerProfileResponseDto> Handle(SignUpMarketerCommand request, CancellationToken cancellationToken)
{ {
if (_currentUserService.UserId == null) if (currentUserService.UserId == null)
throw new AppException("User id is null"); throw new AppException("User id is null");
if (!Guid.TryParse(_currentUserService.UserId, out Guid userId)) if (!Guid.TryParse(currentUserService.UserId, out Guid userId))
throw new AppException("User id is wrong"); throw new AppException("User id is wrong");
var user = await _userManager.FindByIdAsync(_currentUserService.UserId); var user = await userManager.FindByIdAsync(currentUserService.UserId);
if (user == null) if (user == null)
throw new AppException("User not found"); throw new AppException("User not found");
var marketer = await _repositoryWrapper.SetRepository<Marketer>() var marketer = await repositoryWrapper.SetRepository<Marketer>()
.TableNoTracking .TableNoTracking
.FirstOrDefaultAsync(m => m.UserId == userId, cancellationToken); .FirstOrDefaultAsync(m => m.UserId == userId, cancellationToken);
if (marketer != null) if (marketer != null)
return await _mediator.Send(new GetMarketerProfileQuery(MarketerId: marketer.Id), cancellationToken); return await mediator.Send(new GetMarketerProfileQuery(MarketerId: marketer.Id), cancellationToken);
marketer = new Marketer marketer = new Marketer
{ {
@ -38,16 +31,16 @@ public class SignUpMarketerCommandHandler : IRequestHandler<SignUpMarketerComman
FatherName = request.FatherName, FatherName = request.FatherName,
Shaba = request.Shaba, Shaba = request.Shaba,
}; };
_repositoryWrapper.SetRepository<Marketer>() repositoryWrapper.SetRepository<Marketer>()
.Add(marketer); .Add(marketer);
await _repositoryWrapper.SaveChangesAsync(cancellationToken); await repositoryWrapper.SaveChangesAsync(cancellationToken);
user.BirthDate = DateTimeExtensions.UnixTimeStampToDateTime(request.BirthDate); user.BirthDate = DateTimeExtensions.UnixTimeStampToDateTime(request.BirthDate);
user.NationalId = request.NationalId; user.NationalId = request.NationalId;
await _userManager.UpdateAsync(user); await userManager.UpdateAsync(user);
await _mediator.Send(new CreateMarketerDiscountCommand(userId), cancellationToken); await mediator.Send(new CreateMarketerDiscountCommand(userId), cancellationToken);
return await _mediator.Send(new GetMarketerProfileQuery(marketer.Id), cancellationToken); return await mediator.Send(new GetMarketerProfileQuery(marketer.Id), cancellationToken);
} }
} }

View File

@ -1,31 +1,24 @@
namespace Netina.Core.EntityServices.OrderBagHandlers; namespace Netina.Core.EntityServices.OrderBagHandlers;
public class AddToOrderBagCommandHandler : IRequestHandler<AddToOrderBagCommand, OrderSDto> public class AddToOrderBagCommandHandler(
IMediator mediator,
IRepositoryWrapper repositoryWrapper,
ICurrentUserService currentUserService)
: IRequestHandler<AddToOrderBagCommand, OrderSDto>
{ {
private readonly IMediator _mediator;
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly ICurrentUserService _currentUserService;
public AddToOrderBagCommandHandler(IMediator mediator, IRepositoryWrapper repositoryWrapper,ICurrentUserService currentUserService)
{
_mediator = mediator;
_repositoryWrapper = repositoryWrapper;
_currentUserService = currentUserService;
}
public async Task<OrderSDto> Handle(AddToOrderBagCommand request, CancellationToken cancellationToken) public async Task<OrderSDto> Handle(AddToOrderBagCommand request, CancellationToken cancellationToken)
{ {
if (_currentUserService.UserId == null) if (currentUserService.UserId == null)
throw new AppException("Customer id notfound", ApiResultStatusCode.BadRequest); throw new AppException("Customer id notfound", ApiResultStatusCode.BadRequest);
if (!Guid.TryParse(_currentUserService.UserId, out Guid userId)) if (!Guid.TryParse(currentUserService.UserId, out Guid userId))
throw new AppException("Customer id wrong", ApiResultStatusCode.BadRequest); throw new AppException("Customer id wrong", ApiResultStatusCode.BadRequest);
var orderBag = await _mediator.Send(new GetUserOrderBagQuery(), cancellationToken); var orderBag = await mediator.Send(new GetUserOrderBagQuery(), cancellationToken);
foreach (var requestDto in request.RequestDtos) foreach (var requestDto in request.RequestDtos)
{ {
var product = await _repositoryWrapper.SetRepository<Product>() var product = await repositoryWrapper.SetRepository<Product>()
.TableNoTracking .TableNoTracking
.FirstOrDefaultAsync(p => p.Id == requestDto.ProductId, cancellationToken); .FirstOrDefaultAsync(p => p.Id == requestDto.ProductId, cancellationToken);
@ -35,16 +28,16 @@ public class AddToOrderBagCommandHandler : IRequestHandler<AddToOrderBagCommand,
throw new AppException("Product is not enable", ApiResultStatusCode.BadRequest); throw new AppException("Product is not enable", ApiResultStatusCode.BadRequest);
var productSDto = product.AdaptToSDto(); var productSDto = product.AdaptToSDto();
await _mediator.Send(new CalculateProductDiscountCommand(productSDto), cancellationToken); await mediator.Send(new CalculateProductDiscountCommand(productSDto), cancellationToken);
orderBag.AddToOrderBag(productSDto.Id, productSDto.Cost, productSDto.CostWithDiscount, orderBag.AddToOrderBag(productSDto.Id, productSDto.Cost, productSDto.CostWithDiscount,
productSDto.HasDiscount, productSDto.PackingCost, productSDto.CategoryId, requestDto.Count); productSDto.HasDiscount, productSDto.PackingCost, productSDto.CategoryId,productSDto.BrandId, requestDto.Count);
} }
_repositoryWrapper.SetRepository<Order>().Update(orderBag); repositoryWrapper.SetRepository<Order>().Update(orderBag);
await _repositoryWrapper.SaveChangesAsync(cancellationToken); await repositoryWrapper.SaveChangesAsync(cancellationToken);
var order = await _mediator.Send(new CalculateOrderCommand(orderBag.Id), cancellationToken); var order = await mediator.Send(new CalculateOrderCommand(orderBag.Id), cancellationToken);
return order.AdaptToSDto(); return order.AdaptToSDto();
} }

View File

@ -1,22 +1,15 @@
namespace Netina.Core.EntityServices.OrderBagHandlers; namespace Netina.Core.EntityServices.OrderBagHandlers;
public class CheckOrderBagCommandHandler : IRequestHandler<CheckOrderBagCommand , List<CheckOrderBagResponseItem>> public class CheckOrderBagCommandHandler(IRepositoryWrapper repositoryWrapper, IMediator mediator)
: IRequestHandler<CheckOrderBagCommand, List<CheckOrderBagResponseItem>>
{ {
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly IMediator _mediator;
public CheckOrderBagCommandHandler(IRepositoryWrapper repositoryWrapper,IMediator mediator)
{
_repositoryWrapper = repositoryWrapper;
_mediator = mediator;
}
public async Task<List<CheckOrderBagResponseItem>> Handle(CheckOrderBagCommand request, CancellationToken cancellationToken) public async Task<List<CheckOrderBagResponseItem>> Handle(CheckOrderBagCommand request, CancellationToken cancellationToken)
{ {
List<CheckOrderBagResponseItem> response = new List<CheckOrderBagResponseItem>(); List<CheckOrderBagResponseItem> response = new List<CheckOrderBagResponseItem>();
foreach (var item in request.OrderBag) foreach (var item in request.OrderBag)
{ {
var product = await _repositoryWrapper.SetRepository<Product>() var product = await repositoryWrapper.SetRepository<Product>()
.TableNoTracking .TableNoTracking
.Where(p => p.Id == item.ProductId) .Where(p => p.Id == item.ProductId)
.Select(ProductMapper.ProjectToSDto) .Select(ProductMapper.ProjectToSDto)
@ -35,7 +28,7 @@ public class CheckOrderBagCommandHandler : IRequestHandler<CheckOrderBagCommand
} }
else else
{ {
await _mediator.Send(new CalculateProductDiscountCommand(product), cancellationToken); await mediator.Send(new CalculateProductDiscountCommand(product), cancellationToken);
var res = new CheckOrderBagResponseItem var res = new CheckOrderBagResponseItem
{ {
ProductId = item.ProductId, ProductId = item.ProductId,

View File

@ -1,25 +1,19 @@
namespace Netina.Core.EntityServices.OrderBagHandlers; namespace Netina.Core.EntityServices.OrderBagHandlers;
public class GetUserOrderBagQueryHandler : IRequestHandler<GetUserOrderBagQuery,Order> public class GetUserOrderBagQueryHandler(
IRepositoryWrapper repositoryWrapper,
ICurrentUserService currentUserService,
IMediator mediator)
: IRequestHandler<GetUserOrderBagQuery, Order>
{ {
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly ICurrentUserService _currentUserService;
private readonly IMediator _mediator;
public GetUserOrderBagQueryHandler(IRepositoryWrapper repositoryWrapper,ICurrentUserService currentUserService,IMediator mediator)
{
_repositoryWrapper = repositoryWrapper;
_currentUserService = currentUserService;
_mediator = mediator;
}
public async Task<Order> Handle(GetUserOrderBagQuery request, CancellationToken cancellationToken) public async Task<Order> Handle(GetUserOrderBagQuery request, CancellationToken cancellationToken)
{ {
if (_currentUserService.UserId == null) if (currentUserService.UserId == null)
throw new AppException("Customer id notfound", ApiResultStatusCode.BadRequest); throw new AppException("Customer id notfound", ApiResultStatusCode.BadRequest);
if (!Guid.TryParse(_currentUserService.UserId, out Guid userId)) if (!Guid.TryParse(currentUserService.UserId, out Guid userId))
throw new AppException("Customer id wrong",ApiResultStatusCode.BadRequest); throw new AppException("Customer id wrong",ApiResultStatusCode.BadRequest);
var customer = await _repositoryWrapper.SetRepository<Customer>() var customer = await repositoryWrapper.SetRepository<Customer>()
.TableNoTracking .TableNoTracking
.FirstOrDefaultAsync(c => c.UserId == userId, cancellationToken); .FirstOrDefaultAsync(c => c.UserId == userId, cancellationToken);
if (customer == null) if (customer == null)
@ -28,20 +22,20 @@ public class GetUserOrderBagQueryHandler : IRequestHandler<GetUserOrderBagQuery,
{ {
UserId = userId UserId = userId
}; };
_repositoryWrapper.SetRepository<Customer>() repositoryWrapper.SetRepository<Customer>()
.Add(customer); .Add(customer);
await _repositoryWrapper.SaveChangesAsync(cancellationToken); await repositoryWrapper.SaveChangesAsync(cancellationToken);
} }
var order = await _repositoryWrapper.SetRepository<Order>() var order = await repositoryWrapper.SetRepository<Order>()
.TableNoTracking .TableNoTracking
.FirstOrDefaultAsync(o => o.CustomerId == customer.Id && o.OrderStatus == OrderStatus.OrderBag,cancellationToken); .FirstOrDefaultAsync(o => o.CustomerId == customer.Id && o.OrderStatus == OrderStatus.OrderBag,cancellationToken);
if (order == null) if (order == null)
order = await _mediator.Send(new CreateBaseOrderCommand(userId),cancellationToken); order = await mediator.Send(new CreateBaseOrderCommand(userId),cancellationToken);
else else
{ {
var orderProducts = await _repositoryWrapper.SetRepository<OrderProduct>() var orderProducts = await repositoryWrapper.SetRepository<OrderProduct>()
.TableNoTracking .TableNoTracking
.Where(op=>op.OrderId==order.Id) .Where(op=>op.OrderId==order.Id)
.ToListAsync(cancellationToken); .ToListAsync(cancellationToken);

View File

@ -1,29 +1,23 @@
namespace Netina.Core.EntityServices.OrderBagHandlers; namespace Netina.Core.EntityServices.OrderBagHandlers;
public class RemoveFromOrderBagCommandHandler : IRequestHandler<RemoveFromOrderBagCommand, OrderSDto> public class RemoveFromOrderBagCommandHandler(
ICurrentUserService currentUserService,
IRepositoryWrapper repositoryWrapper,
IMediator mediator)
: IRequestHandler<RemoveFromOrderBagCommand, OrderSDto>
{ {
private readonly ICurrentUserService _currentUserService;
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly IMediator _mediator;
public RemoveFromOrderBagCommandHandler(ICurrentUserService currentUserService, IRepositoryWrapper repositoryWrapper,IMediator mediator)
{
_currentUserService = currentUserService;
_repositoryWrapper = repositoryWrapper;
_mediator = mediator;
}
public async Task<OrderSDto> Handle(RemoveFromOrderBagCommand request, CancellationToken cancellationToken) public async Task<OrderSDto> Handle(RemoveFromOrderBagCommand request, CancellationToken cancellationToken)
{ {
if (_currentUserService.UserId == null) if (currentUserService.UserId == null)
throw new AppException("Customer id notfound", ApiResultStatusCode.BadRequest); throw new AppException("Customer id notfound", ApiResultStatusCode.BadRequest);
if (!Guid.TryParse(_currentUserService.UserId, out Guid userId)) if (!Guid.TryParse(currentUserService.UserId, out Guid userId))
throw new AppException("Customer id wrong", ApiResultStatusCode.BadRequest); throw new AppException("Customer id wrong", ApiResultStatusCode.BadRequest);
var orderBag = await _mediator.Send(new GetUserOrderBagQuery(), cancellationToken); var orderBag = await mediator.Send(new GetUserOrderBagQuery(), cancellationToken);
foreach (var requestDto in request.RequestDtos) foreach (var requestDto in request.RequestDtos)
{ {
var product = await _repositoryWrapper.SetRepository<Product>() var product = await repositoryWrapper.SetRepository<Product>()
.TableNoTracking .TableNoTracking
.FirstOrDefaultAsync(p => p.Id == requestDto.ProductId, cancellationToken); .FirstOrDefaultAsync(p => p.Id == requestDto.ProductId, cancellationToken);
@ -37,9 +31,9 @@ public class RemoveFromOrderBagCommandHandler : IRequestHandler<RemoveFromOrderB
} }
_repositoryWrapper.SetRepository<Order>().Update(orderBag); repositoryWrapper.SetRepository<Order>().Update(orderBag);
await _repositoryWrapper.SaveChangesAsync(cancellationToken); await repositoryWrapper.SaveChangesAsync(cancellationToken);
var order = await _mediator.Send(new CalculateOrderCommand(orderBag.Id), cancellationToken); var order = await mediator.Send(new CalculateOrderCommand(orderBag.Id), cancellationToken);
return order.AdaptToSDto(); return order.AdaptToSDto();
} }

View File

@ -0,0 +1,38 @@
namespace Netina.Core.EntityServices.OrderBagHandlers;
public class SubmitDiscountActionCommandHandler(IRepositoryWrapper repositoryWrapper, IMediator mediator)
: IRequestHandler<SubmitDiscountActionCommand, OrderSDto>
{
public async Task<OrderSDto> Handle(SubmitDiscountActionCommand request, CancellationToken cancellationToken)
{
var order = await repositoryWrapper.SetRepository<Order>()
.TableNoTracking
.FirstOrDefaultAsync(o => o.Id == request.OrderId, cancellationToken);
if (order == null)
throw new AppException("Order not found", ApiResultStatusCode.NotFound);
if (request.DiscountCode != null)
{
var discount = await repositoryWrapper.SetRepository<Discount>()
.TableNoTracking
.FirstOrDefaultAsync(d => d.Code == request.DiscountCode, cancellationToken);
if (discount == null || discount.IsExpired())
throw new AppException("تخفیف منقضی شده است یا وجود ندارد", ApiResultStatusCode.NotFound);
var isFirstUserOfDiscount = await mediator.Send(new CheckUserDiscountFirstUseCommand(request.DiscountCode), cancellationToken);
if (!isFirstUserOfDiscount)
throw new BaseApiException(ApiResultStatusCode.BadRequest, "شما یک بار از این کد تخفیف استفاده نموده اید و قابلیت استفاده مجدد ندارید");
order.SetDiscount(request.DiscountCode);
}
else
order.RemoveDiscount();
repositoryWrapper.SetRepository<Order>().Update(order);
await repositoryWrapper.SaveChangesAsync(cancellationToken);
var calculateOrder = await mediator.Send(new CalculateOrderCommand(order.Id), cancellationToken);
return calculateOrder.AdaptToSDto();
}
}

View File

@ -1,32 +0,0 @@
namespace Netina.Core.EntityServices.OrderBagHandlers;
public class SubmitDiscountCommandHandler : IRequestHandler<SubmitDiscountCommand,OrderSDto>
{
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly IMediator _mediator;
public SubmitDiscountCommandHandler(IRepositoryWrapper repositoryWrapper,IMediator mediator)
{
_repositoryWrapper = repositoryWrapper;
_mediator = mediator;
}
public async Task<OrderSDto> Handle(SubmitDiscountCommand request, CancellationToken cancellationToken)
{
var order = await _repositoryWrapper.SetRepository<Order>()
.TableNoTracking
.FirstOrDefaultAsync(o => o.Id == request.OrderId, cancellationToken);
if (order == null)
throw new AppException("Order not found", ApiResultStatusCode.NotFound);
var discount = await _repositoryWrapper.SetRepository<Discount>()
.TableNoTracking
.FirstOrDefaultAsync(d => d.Code == request.DiscountCode, cancellationToken);
if (discount == null || discount.IsExpired())
throw new AppException("تخفیف منقضی شده است یا وجود ندارد", ApiResultStatusCode.NotFound);
order.SetDiscount(request.DiscountCode);
_repositoryWrapper.SetRepository<Order>().Update(order);
await _repositoryWrapper.SaveChangesAsync(cancellationToken);
var calculateOrder = await _mediator.Send(new CalculateOrderCommand(order.Id), cancellationToken);
return calculateOrder.AdaptToSDto();
}
}

View File

@ -1,31 +1,24 @@
namespace Netina.Core.EntityServices.OrderBagHandlers; namespace Netina.Core.EntityServices.OrderBagHandlers;
public class SubmitOrderBagCommandHandler : IRequestHandler<SubmitOrderBagCommand,OrderSDto> public class SubmitOrderBagCommandHandler(
IMediator mediator,
IRepositoryWrapper repositoryWrapper,
ICurrentUserService currentUserService)
: IRequestHandler<SubmitOrderBagCommand, OrderSDto>
{ {
private readonly IMediator _mediator;
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly ICurrentUserService _currentUserService;
public SubmitOrderBagCommandHandler(IMediator mediator, IRepositoryWrapper repositoryWrapper, ICurrentUserService currentUserService)
{
_mediator = mediator;
_repositoryWrapper = repositoryWrapper;
_currentUserService = currentUserService;
}
public async Task<OrderSDto> Handle(SubmitOrderBagCommand request, CancellationToken cancellationToken) public async Task<OrderSDto> Handle(SubmitOrderBagCommand request, CancellationToken cancellationToken)
{ {
if (_currentUserService.UserId == null) if (currentUserService.UserId == null)
throw new AppException("Customer id notfound", ApiResultStatusCode.BadRequest); throw new AppException("Customer id notfound", ApiResultStatusCode.BadRequest);
if (!Guid.TryParse(_currentUserService.UserId, out Guid userId)) if (!Guid.TryParse(currentUserService.UserId, out Guid userId))
throw new AppException("Customer id wrong", ApiResultStatusCode.BadRequest); throw new AppException("Customer id wrong", ApiResultStatusCode.BadRequest);
var orderBag = await _mediator.Send(new GetUserOrderBagQuery(), cancellationToken); var orderBag = await mediator.Send(new GetUserOrderBagQuery(), cancellationToken);
foreach (var requestDto in request.RequestDtos) foreach (var requestDto in request.RequestDtos)
{ {
var product = await _repositoryWrapper.SetRepository<Product>() var product = await repositoryWrapper.SetRepository<Product>()
.TableNoTracking .TableNoTracking
.FirstOrDefaultAsync(p => p.Id == requestDto.ProductId, cancellationToken); .FirstOrDefaultAsync(p => p.Id == requestDto.ProductId, cancellationToken);
@ -35,25 +28,25 @@ public class SubmitOrderBagCommandHandler : IRequestHandler<SubmitOrderBagComman
throw new AppException("Product is not enable", ApiResultStatusCode.BadRequest); throw new AppException("Product is not enable", ApiResultStatusCode.BadRequest);
var productSDto = product.AdaptToSDto(); var productSDto = product.AdaptToSDto();
await _mediator.Send(new CalculateProductDiscountCommand(productSDto), cancellationToken); await mediator.Send(new CalculateProductDiscountCommand(productSDto), cancellationToken);
orderBag.ChangeOrderBag(productSDto.Id, productSDto.Cost, productSDto.CostWithDiscount, orderBag.ChangeOrderBag(productSDto.Id, productSDto.Cost, productSDto.CostWithDiscount,
productSDto.HasDiscount, productSDto.PackingCost, productSDto.CategoryId, requestDto.Count); productSDto.HasDiscount, productSDto.PackingCost, productSDto.CategoryId,productSDto.BrandId, requestDto.Count);
} }
foreach (var orderProduct in orderBag.OrderProducts.ToList()) foreach (var orderProduct in orderBag.OrderProducts.ToList())
{ {
if(request.RequestDtos.FirstOrDefault(op=>op.ProductId==orderProduct.ProductId)==null) if(request.RequestDtos.FirstOrDefault(op=>op.ProductId==orderProduct.ProductId)==null)
{ {
orderBag.OrderProducts.Remove(orderProduct); orderBag.OrderProducts.Remove(orderProduct);
_repositoryWrapper.SetRepository<OrderProduct>().Delete(orderProduct); repositoryWrapper.SetRepository<OrderProduct>().Delete(orderProduct);
await _repositoryWrapper.SaveChangesAsync(cancellationToken); await repositoryWrapper.SaveChangesAsync(cancellationToken);
} }
} }
_repositoryWrapper.SetRepository<Order>().Update(orderBag); repositoryWrapper.SetRepository<Order>().Update(orderBag);
await _repositoryWrapper.SaveChangesAsync(cancellationToken); await repositoryWrapper.SaveChangesAsync(cancellationToken);
var order = await _mediator.Send(new CalculateOrderCommand(orderBag.Id), cancellationToken); var order = await mediator.Send(new CalculateOrderCommand(orderBag.Id), cancellationToken);
return order.AdaptToSDto(); return order.AdaptToSDto();
} }

View File

@ -2,26 +2,19 @@
namespace Netina.Core.EntityServices.OrderBagHandlers; namespace Netina.Core.EntityServices.OrderBagHandlers;
public class SubmitOrderDeliveryCommandHandler : IRequestHandler<SubmitOrderDeliveryCommand, OrderSDto> public class SubmitOrderDeliveryCommandHandler(IMediator mediator, IRepositoryWrapper repositoryWrapper)
: IRequestHandler<SubmitOrderDeliveryCommand, OrderSDto>
{ {
private readonly IMediator _mediator;
private readonly IRepositoryWrapper _repositoryWrapper;
public SubmitOrderDeliveryCommandHandler(IMediator mediator, IRepositoryWrapper repositoryWrapper)
{
_mediator = mediator;
_repositoryWrapper = repositoryWrapper;
}
public async Task<OrderSDto> Handle(SubmitOrderDeliveryCommand request, CancellationToken cancellationToken) public async Task<OrderSDto> Handle(SubmitOrderDeliveryCommand request, CancellationToken cancellationToken)
{ {
var order = await _repositoryWrapper.SetRepository<Order>() var order = await repositoryWrapper.SetRepository<Order>()
.TableNoTracking .TableNoTracking
.FirstOrDefaultAsync(o => o.Id == request.OrderId, cancellationToken); .FirstOrDefaultAsync(o => o.Id == request.OrderId, cancellationToken);
if (order == null) if (order == null)
throw new AppException("Order not found", ApiResultStatusCode.NotFound); throw new AppException("Order not found", ApiResultStatusCode.NotFound);
var orderDelivery = await _repositoryWrapper.SetRepository<OrderDelivery>() var orderDelivery = await repositoryWrapper.SetRepository<OrderDelivery>()
.TableNoTracking .TableNoTracking
.FirstOrDefaultAsync(od => od.OrderId == request.OrderId, cancellationToken); .FirstOrDefaultAsync(od => od.OrderId == request.OrderId, cancellationToken);
if (orderDelivery != null) if (orderDelivery != null)
@ -29,7 +22,7 @@ public class SubmitOrderDeliveryCommandHandler : IRequestHandler<SubmitOrderDeli
order.AddOrderDelivery(orderDelivery.AddressId, orderDelivery.DeliveryCost, orderDelivery.ShippingId, orderDelivery.OrderId, orderDelivery.Id); order.AddOrderDelivery(orderDelivery.AddressId, orderDelivery.DeliveryCost, orderDelivery.ShippingId, orderDelivery.OrderId, orderDelivery.Id);
} }
var shipping = await _repositoryWrapper.SetRepository<Shipping>() var shipping = await repositoryWrapper.SetRepository<Shipping>()
.TableNoTracking .TableNoTracking
.FirstOrDefaultAsync(s => s.Id == request.ShippingId, cancellationToken); .FirstOrDefaultAsync(s => s.Id == request.ShippingId, cancellationToken);
if (shipping == null) if (shipping == null)
@ -37,10 +30,10 @@ public class SubmitOrderDeliveryCommandHandler : IRequestHandler<SubmitOrderDeli
order.AddOrderDelivery(request.AddressId, shipping.DeliveryCost, request.ShippingId, request.OrderId); order.AddOrderDelivery(request.AddressId, shipping.DeliveryCost, request.ShippingId, request.OrderId);
_repositoryWrapper.SetRepository<Order>().Update(order); repositoryWrapper.SetRepository<Order>().Update(order);
await _repositoryWrapper.SaveChangesAsync(cancellationToken); await repositoryWrapper.SaveChangesAsync(cancellationToken);
var calculatedOrder = await _mediator.Send(new CalculateOrderCommand(order.Id), cancellationToken); var calculatedOrder = await mediator.Send(new CalculateOrderCommand(order.Id), cancellationToken);
return calculatedOrder.AdaptToSDto(); return calculatedOrder.AdaptToSDto();
} }
} }

View File

@ -1,10 +1,14 @@
namespace Netina.Core.EntityServices.OrderHandlers; namespace Netina.Core.EntityServices.OrderHandlers;
public class CalculateOrderCommandHandler(IRepositoryWrapper repositoryWrapper, IMediator mediator) : IRequestHandler<CalculateOrderCommand,Order> public class CalculateOrderCommandHandler(IRepositoryWrapper repositoryWrapper, IMediator mediator,ISettingService settingService) : IRequestHandler<CalculateOrderCommand,Order>
{ {
public async Task<Order> Handle(CalculateOrderCommand request, CancellationToken cancellationToken) public async Task<Order> Handle(CalculateOrderCommand request, CancellationToken cancellationToken)
{ {
var setting = await settingService.GetSettingAsync("ShopSetting", cancellationToken);
double taxesFee = 9;
if (setting is ShopSetting shopSetting)
taxesFee = shopSetting.TaxesFee;
var order = await mediator.Send(new GetOrderQuery(request.OrderId), cancellationToken); var order = await mediator.Send(new GetOrderQuery(request.OrderId), cancellationToken);
if (order.OrderStatus != OrderStatus.OrderBag) if (order.OrderStatus != OrderStatus.OrderBag)
throw new AppException("Order is not in bag status and cant be calculate", ApiResultStatusCode.BadRequest); throw new AppException("Order is not in bag status and cant be calculate", ApiResultStatusCode.BadRequest);
@ -19,12 +23,21 @@ public class CalculateOrderCommandHandler(IRepositoryWrapper repositoryWrapper,
var deliveryPrice = order.OrderDelivery?.DeliveryCost ?? 0; var deliveryPrice = order.OrderDelivery?.DeliveryCost ?? 0;
double productDiscountPrice = order.OrderProducts.Sum(op=>(op.ProductFee - op.ProductFeeWithDiscount) * op.Count); double productDiscountPrice = order.OrderProducts.Sum(op=>(op.ProductFee - op.ProductFeeWithDiscount) * op.Count);
double discountCodePrice = 0; double discountCodePrice = 0;
if (!order.DiscountCode.IsNullOrEmpty())
discountCodePrice += await mediator.Send(new CalculateOrderDiscountCommand(order.DiscountCode, order),cancellationToken);
//var taxesPrice = (((totalProductPrice - discountPrice) + totalPackingPrice + servicePrice) / 100) * _shopSettings.TaxesFee; try
{
if (!order.DiscountCode.IsNullOrEmpty())
discountCodePrice += await mediator.Send(new CalculateOrderDiscountCommand(order.DiscountCode, order),
cancellationToken);
}
catch (Exception )
{
order.RemoveDiscount();
}
var taxesPrice = 0; if (totalProductPrice > 5000000)
deliveryPrice = 0;
var taxesPrice = (((totalProductPrice - (discountCodePrice + productDiscountPrice)) + totalPackingPrice + servicePrice) / 100) * taxesFee;
order.SetTotalPrice(totalProductPrice, totalPackingPrice, servicePrice, deliveryPrice, productDiscountPrice, discountCodePrice, taxesPrice); order.SetTotalPrice(totalProductPrice, totalPackingPrice, servicePrice, deliveryPrice, productDiscountPrice, discountCodePrice, taxesPrice);
order.OrderProducts.Clear(); order.OrderProducts.Clear();

View File

@ -0,0 +1,21 @@
namespace Netina.Core.EntityServices.OrderHandlers;
public class CancelOrderStepCommandHandler (IRepositoryWrapper repositoryWrapper) : IRequestHandler<CancelOrderStepCommand,bool>
{
public async Task<bool> Handle(CancelOrderStepCommand request, CancellationToken cancellationToken)
{
var order = await repositoryWrapper.SetRepository<Order>()
.TableNoTracking
.FirstOrDefaultAsync(o => o.Id == request.OrderId, cancellationToken);
if (order == null)
throw new AppException("Order not found", ApiResultStatusCode.NotFound);
order.SetOrderStatus(OrderStatus.Canceled);
repositoryWrapper.SetRepository<Order>().Update(order);
await repositoryWrapper.SaveChangesAsync(cancellationToken);
return true;
}
}

View File

@ -1,23 +0,0 @@
namespace Netina.Core.EntityServices.ReviewHandlers;
public class ConfirmReviewCommandHandler : IRequestHandler<ConfirmReviewCommand , bool>
{
private readonly IRepositoryWrapper _repositoryWrapper;
public ConfirmReviewCommandHandler(IRepositoryWrapper repositoryWrapper)
{
_repositoryWrapper = repositoryWrapper;
}
public async Task<bool> Handle(ConfirmReviewCommand request, CancellationToken cancellationToken)
{
var review = await _repositoryWrapper.SetRepository<Review>().TableNoTracking
.FirstOrDefaultAsync(r => r.Id == request.Id, cancellationToken);
if (review == null)
throw new AppException("Review not found", ApiResultStatusCode.NotFound);
review.ConfirmReview();
_repositoryWrapper.SetRepository<Review>().Update(review);
await _repositoryWrapper.SaveChangesAsync(cancellationToken);
return true;
}
}

View File

@ -1,33 +1,19 @@
namespace Netina.Core.EntityServices; namespace Netina.Core.EntityServices;
public class UserService : IUserService public class UserService(
ICurrentUserService currentUserService,
UserManager<ApplicationUser> userManager,
RoleManager<ApplicationRole> roleManager,
IExternalFilesService externalFilesService,
IRepositoryWrapper repositoryWrapper)
: IUserService
{ {
private readonly ICurrentUserService _currentUserService;
private readonly UserManager<ApplicationUser> _userManager;
private readonly RoleManager<ApplicationRole> _roleManager;
private readonly IExternalFilesService _externalFilesService;
private readonly IRepositoryWrapper _repositoryWrapper;
public UserService(ICurrentUserService currentUserService,
UserManager<ApplicationUser> userManager,
RoleManager<ApplicationRole> roleManager,
IExternalFilesService externalFilesService,
IRepositoryWrapper repositoryWrapper)
{
_currentUserService = currentUserService;
_userManager = userManager;
_roleManager = roleManager;
_externalFilesService = externalFilesService;
_repositoryWrapper = repositoryWrapper;
}
public async Task<ProfileResponseDto> GetUserProfileAsync(CancellationToken cancellationToken) public async Task<ProfileResponseDto> GetUserProfileAsync(CancellationToken cancellationToken)
{ {
if (!Guid.TryParse(_currentUserService.UserId, out var userId)) if (!Guid.TryParse(currentUserService.UserId, out var userId))
throw new AppException("Wrong Token", ApiResultStatusCode.UnAuthorized); throw new AppException("Wrong Token", ApiResultStatusCode.UnAuthorized);
var user = await _userManager.FindByIdAsync(userId.ToString()); var user = await userManager.FindByIdAsync(userId.ToString());
if (user == null) if (user == null)
throw new AppException("User NotFound", ApiResultStatusCode.NotFound); throw new AppException("User NotFound", ApiResultStatusCode.NotFound);
@ -36,14 +22,14 @@ public class UserService : IUserService
//var userSDto = user.AdaptToSDto(); //var userSDto = user.AdaptToSDto();
response.User = new ApplicationUserSDto(); response.User = new ApplicationUserSDto();
var userRoles = await _userManager.GetRolesAsync(user); var userRoles = await userManager.GetRolesAsync(user);
foreach (var role in userRoles) foreach (var role in userRoles)
{ {
var dbRole = await _roleManager.FindByNameAsync(role); var dbRole = await roleManager.FindByNameAsync(role);
if (dbRole != null) if (dbRole != null)
{ {
var roleClaims = await _roleManager.GetClaimsAsync(dbRole); var roleClaims = await roleManager.GetClaimsAsync(dbRole);
response.Permissions.AddRange(roleClaims.Where(c => c.Type == "Permission").Select(c => c.Value).ToList()); response.Permissions.AddRange(roleClaims.Where(c => c.Type == "Permission").Select(c => c.Value).ToList());
} }
} }
@ -57,23 +43,23 @@ public class UserService : IUserService
List<ApplicationUserSDto> users; List<ApplicationUserSDto> users;
if (phoneNumber == null || phoneNumber.IsNullOrEmpty()) if (phoneNumber == null || phoneNumber.IsNullOrEmpty())
users = await _userManager.Users users = await userManager.Users
.Where(u => u.UserName != "09214802813") .Where(u => u.UserName != "09214802813")
.Skip(page * 15).Take(15) .Skip(page * 15).Take(15)
.Select(ApplicationUserMapper.ProjectToSDto) .Select(ApplicationUserMapper.ProjectToSDto)
.ToListAsync(cancellationToken); .ToListAsync(cancellationToken);
else else
users = await _userManager.Users users = await userManager.Users
.Where(a => a.PhoneNumber == phoneNumber && a.UserName != "09214802813") .Where(a => a.PhoneNumber == phoneNumber && a.UserName != "09214802813")
.Skip(page * 15).Take(15) .Skip(page * 15).Take(15)
.Select(ApplicationUserMapper.ProjectToSDto) .Select(ApplicationUserMapper.ProjectToSDto)
.ToListAsync(cancellationToken); .ToListAsync(cancellationToken);
foreach (var user in users) foreach (var user in users)
{ {
var roles = await _userManager.GetRolesAsync(user.AdaptToApplicationUser()); var roles = await userManager.GetRolesAsync(user.AdaptToApplicationUser());
foreach (var roleName in roles) foreach (var roleName in roles)
{ {
var role = await _roleManager.FindByNameAsync(roleName); var role = await roleManager.FindByNameAsync(roleName);
if (role != null) if (role != null)
user.RoleName += role.PersianName + " "; user.RoleName += role.PersianName + " ";
} }
@ -85,20 +71,20 @@ public class UserService : IUserService
public async Task<ApplicationUserSDto> GetUserAsync(Guid userId, CancellationToken cancellationToken = default) public async Task<ApplicationUserSDto> GetUserAsync(Guid userId, CancellationToken cancellationToken = default)
{ {
var user = await _userManager.FindByIdAsync(userId.ToString()); var user = await userManager.FindByIdAsync(userId.ToString());
if (user == null) if (user == null)
throw new AppException("User not found", ApiResultStatusCode.NotFound); throw new AppException("User not found", ApiResultStatusCode.NotFound);
var dto = user.AdaptToSDto(); var dto = user.AdaptToSDto();
dto.IsMarketer = await _repositoryWrapper.SetRepository<Marketer>() dto.IsMarketer = await repositoryWrapper.SetRepository<Marketer>()
.TableNoTracking .TableNoTracking
.AnyAsync(m => m.UserId == userId, cancellationToken); .AnyAsync(m => m.UserId == userId, cancellationToken);
dto.IsManager = await _repositoryWrapper.SetRepository<Manager>() dto.IsManager = await repositoryWrapper.SetRepository<Manager>()
.TableNoTracking .TableNoTracking
.AnyAsync(m => m.UserId == userId, cancellationToken); .AnyAsync(m => m.UserId == userId, cancellationToken);
var roles = await _userManager.GetRolesAsync(user); var roles = await userManager.GetRolesAsync(user);
foreach (var roleName in roles) foreach (var roleName in roles)
{ {
var role = await _roleManager.FindByNameAsync(roleName); var role = await roleManager.FindByNameAsync(roleName);
if (role != null) if (role != null)
dto.RoleIds.Add(role.Id); dto.RoleIds.Add(role.Id);
} }
@ -113,7 +99,7 @@ public class UserService : IUserService
PhoneNumber = phoneNumber, PhoneNumber = phoneNumber,
SignUpStatus = SignUpStatus.StartSignOn SignUpStatus = SignUpStatus.StartSignOn
}; };
var result = await _userManager.CreateAsync(user); var result = await userManager.CreateAsync(user);
if (!result.Succeeded) if (!result.Succeeded)
throw new AppException(string.Join('|', result.Errors)); throw new AppException(string.Join('|', result.Errors));
return user; return user;
@ -122,7 +108,7 @@ public class UserService : IUserService
public async Task<ApplicationUser> CreateUserAsync(UserActionRequestDto request, CancellationToken cancellationToken) public async Task<ApplicationUser> CreateUserAsync(UserActionRequestDto request, CancellationToken cancellationToken)
{ {
var user = await _userManager.FindByNameAsync(request.PhoneNumber); var user = await userManager.FindByNameAsync(request.PhoneNumber);
if (user == null) if (user == null)
{ {
user = new ApplicationUser user = new ApplicationUser
@ -140,13 +126,13 @@ public class UserService : IUserService
if (!request.Password.IsNullOrEmpty()) if (!request.Password.IsNullOrEmpty())
{ {
var result = await _userManager.CreateAsync(user, request.Password); var result = await userManager.CreateAsync(user, request.Password);
if (!result.Succeeded) if (!result.Succeeded)
throw new AppException(string.Join('|', result.Errors.Select(e => e.Description))); throw new AppException(string.Join('|', result.Errors.Select(e => e.Description)));
} }
else else
{ {
var result = await _userManager.CreateAsync(user); var result = await userManager.CreateAsync(user);
if (!result.Succeeded) if (!result.Succeeded)
throw new AppException(string.Join('|', result.Errors.Select(e => e.Description))); throw new AppException(string.Join('|', result.Errors.Select(e => e.Description)));
} }
@ -155,31 +141,31 @@ public class UserService : IUserService
{ {
foreach (var roleId in request.RoleIds) foreach (var roleId in request.RoleIds)
{ {
var role = await _roleManager.FindByIdAsync(roleId.ToString()); var role = await roleManager.FindByIdAsync(roleId.ToString());
if (role is { Name: not null }) if (role is { Name: not null })
await _userManager.AddToRoleAsync(user, role.Name); await userManager.AddToRoleAsync(user, role.Name);
} }
} }
var customer = await _repositoryWrapper.SetRepository<Customer>() var customer = await repositoryWrapper.SetRepository<Customer>()
.TableNoTracking .TableNoTracking
.FirstOrDefaultAsync(c => c.UserId == user.Id, cancellationToken); .FirstOrDefaultAsync(c => c.UserId == user.Id, cancellationToken);
if (customer != null) if (customer != null)
{ {
_repositoryWrapper.SetRepository<Customer>() repositoryWrapper.SetRepository<Customer>()
.Add(new Customer .Add(new Customer
{ {
UserId = user.Id UserId = user.Id
}); });
await _repositoryWrapper.SaveChangesAsync(default); await repositoryWrapper.SaveChangesAsync(default);
} }
_repositoryWrapper.SetRepository<Manager>() repositoryWrapper.SetRepository<Manager>()
.Add(new Manager .Add(new Manager
{ {
UserId = user.Id UserId = user.Id
}); });
await _repositoryWrapper.SaveChangesAsync(default); await repositoryWrapper.SaveChangesAsync(default);
} }
return user; return user;
} }
@ -189,7 +175,7 @@ public class UserService : IUserService
if (request.UserId == Guid.Empty) if (request.UserId == Guid.Empty)
throw new AppException("Wrong authorize token , UserId needed"); throw new AppException("Wrong authorize token , UserId needed");
var user = await _userManager.FindByIdAsync(request.UserId.ToString()); var user = await userManager.FindByIdAsync(request.UserId.ToString());
if (user == null) if (user == null)
throw new AppException("User not found", ApiResultStatusCode.NotFound); throw new AppException("User not found", ApiResultStatusCode.NotFound);
user.LastName = request.LastName; user.LastName = request.LastName;
@ -202,29 +188,29 @@ public class UserService : IUserService
user.BirthDate = DateTimeExtensions.UnixTimeStampToDateTime(request.BirthDateTimeStamp); user.BirthDate = DateTimeExtensions.UnixTimeStampToDateTime(request.BirthDateTimeStamp);
user.Gender = request.Gender; user.Gender = request.Gender;
var result = await _userManager.UpdateAsync(user); var result = await userManager.UpdateAsync(user);
if (!result.Succeeded) if (!result.Succeeded)
throw new AppException(string.Join('|', result.Errors.Select(e => e.Description))); throw new AppException(string.Join('|', result.Errors.Select(e => e.Description)));
if (!request.Password.IsNullOrEmpty()) if (!request.Password.IsNullOrEmpty())
{ {
if (await _userManager.HasPasswordAsync(user)) if (await userManager.HasPasswordAsync(user))
await _userManager.RemovePasswordAsync(user); await userManager.RemovePasswordAsync(user);
var addPassResult = await _userManager.AddPasswordAsync(user, request.Password); var addPassResult = await userManager.AddPasswordAsync(user, request.Password);
if (!addPassResult.Succeeded) if (!addPassResult.Succeeded)
throw new AppException(string.Join('|', addPassResult.Errors.Select(e => e.Description))); throw new AppException(string.Join('|', addPassResult.Errors.Select(e => e.Description)));
} }
if (request.RoleIds.Count > 0) if (request.RoleIds.Count > 0)
{ {
var userRoles = await _userManager.GetRolesAsync(user); var userRoles = await userManager.GetRolesAsync(user);
await _userManager.RemoveFromRolesAsync(user, userRoles); await userManager.RemoveFromRolesAsync(user, userRoles);
foreach (var roleId in request.RoleIds) foreach (var roleId in request.RoleIds)
{ {
var role = await _roleManager.FindByIdAsync(roleId.ToString()); var role = await roleManager.FindByIdAsync(roleId.ToString());
if (role is { Name: not null }) if (role is { Name: not null })
{ {
await _userManager.AddToRoleAsync(user, role.Name); await userManager.AddToRoleAsync(user, role.Name);
} }
} }
} }
@ -234,10 +220,10 @@ public class UserService : IUserService
public async Task<bool> EditUserProfileAsync(UserActionRequestDto request, CancellationToken cancellationToken) public async Task<bool> EditUserProfileAsync(UserActionRequestDto request, CancellationToken cancellationToken)
{ {
if (_currentUserService.UserId == null) if (currentUserService.UserId == null)
throw new AppException("Wrong authorize token , UserId needed"); throw new AppException("Wrong authorize token , UserId needed");
var user = await _userManager.FindByIdAsync(_currentUserService.UserId); var user = await userManager.FindByIdAsync(currentUserService.UserId);
if (user == null) if (user == null)
throw new AppException("User not found", ApiResultStatusCode.NotFound); throw new AppException("User not found", ApiResultStatusCode.NotFound);
user.LastName = request.LastName; user.LastName = request.LastName;
@ -250,15 +236,15 @@ public class UserService : IUserService
user.BirthDate = DateTimeExtensions.UnixTimeStampToDateTime(request.BirthDateTimeStamp); user.BirthDate = DateTimeExtensions.UnixTimeStampToDateTime(request.BirthDateTimeStamp);
user.Gender = request.Gender; user.Gender = request.Gender;
var result = await _userManager.UpdateAsync(user); var result = await userManager.UpdateAsync(user);
if (!result.Succeeded) if (!result.Succeeded)
throw new AppException(string.Join('|', result.Errors.Select(e => e.Description))); throw new AppException(string.Join('|', result.Errors.Select(e => e.Description)));
if (!request.Password.IsNullOrEmpty()) if (!request.Password.IsNullOrEmpty())
{ {
if (await _userManager.HasPasswordAsync(user)) if (await userManager.HasPasswordAsync(user))
await _userManager.RemovePasswordAsync(user); await userManager.RemovePasswordAsync(user);
var addPassResult = await _userManager.AddPasswordAsync(user, request.Password); var addPassResult = await userManager.AddPasswordAsync(user, request.Password);
if (!addPassResult.Succeeded) if (!addPassResult.Succeeded)
throw new AppException(string.Join('|', addPassResult.Errors.Select(e => e.Description))); throw new AppException(string.Join('|', addPassResult.Errors.Select(e => e.Description)));
} }
@ -268,34 +254,34 @@ public class UserService : IUserService
public async Task<bool> RemoveUserAsync(Guid userId, CancellationToken cancellationToken) public async Task<bool> RemoveUserAsync(Guid userId, CancellationToken cancellationToken)
{ {
var user = await _userManager.FindByIdAsync(userId.ToString()); var user = await userManager.FindByIdAsync(userId.ToString());
if (user == null) if (user == null)
throw new AppException("User not found", ApiResultStatusCode.NotFound); throw new AppException("User not found", ApiResultStatusCode.NotFound);
var roles = await _userManager.GetRolesAsync(user); var roles = await userManager.GetRolesAsync(user);
await _userManager.RemoveFromRolesAsync(user, roles); await userManager.RemoveFromRolesAsync(user, roles);
var removeResult = await _userManager.DeleteAsync(user); var removeResult = await userManager.DeleteAsync(user);
if (!removeResult.Succeeded) if (!removeResult.Succeeded)
throw new AppException(string.Join('|', removeResult.Errors.Select(e => e.Description))); throw new AppException(string.Join('|', removeResult.Errors.Select(e => e.Description)));
var customer = await _repositoryWrapper.SetRepository<Customer>() var customer = await repositoryWrapper.SetRepository<Customer>()
.TableNoTracking .TableNoTracking
.FirstOrDefaultAsync(c => c.UserId == userId, cancellationToken); .FirstOrDefaultAsync(c => c.UserId == userId, cancellationToken);
if (customer != null) if (customer != null)
{ {
_repositoryWrapper.SetRepository<Customer>() repositoryWrapper.SetRepository<Customer>()
.Delete(customer); .Delete(customer);
await _repositoryWrapper.SaveChangesAsync(default); await repositoryWrapper.SaveChangesAsync(default);
} }
var manager = await _repositoryWrapper.SetRepository<Manager>() var manager = await repositoryWrapper.SetRepository<Manager>()
.TableNoTracking .TableNoTracking
.FirstOrDefaultAsync(c => c.UserId == userId, cancellationToken); .FirstOrDefaultAsync(c => c.UserId == userId, cancellationToken);
if (manager != null) if (manager != null)
{ {
_repositoryWrapper.SetRepository<Manager>() repositoryWrapper.SetRepository<Manager>()
.Delete(manager); .Delete(manager);
await _repositoryWrapper.SaveChangesAsync(default); await repositoryWrapper.SaveChangesAsync(default);
} }
return true; return true;
@ -303,26 +289,26 @@ public class UserService : IUserService
public async Task<AdminChangeLogResponseDto> GetAdminChangeLogAsync(CancellationToken cancellationToken = default) public async Task<AdminChangeLogResponseDto> GetAdminChangeLogAsync(CancellationToken cancellationToken = default)
{ {
if (!Guid.TryParse(_currentUserService.UserId, out var userId)) if (!Guid.TryParse(currentUserService.UserId, out var userId))
throw new AppException("Wrong Token", ApiResultStatusCode.UnAuthorized); throw new AppException("Wrong Token", ApiResultStatusCode.UnAuthorized);
var user = await _userManager.FindByIdAsync(userId.ToString()); var user = await userManager.FindByIdAsync(userId.ToString());
if (user == null) if (user == null)
throw new AppException("User NotFound", ApiResultStatusCode.NotFound); throw new AppException("User NotFound", ApiResultStatusCode.NotFound);
var manager = await _repositoryWrapper.SetRepository<Manager>() var manager = await repositoryWrapper.SetRepository<Manager>()
.TableNoTracking .TableNoTracking
.FirstOrDefaultAsync(m => m.UserId == userId, cancellationToken); .FirstOrDefaultAsync(m => m.UserId == userId, cancellationToken);
var currentVersion = await _externalFilesService.GetAdminChangeLogAsync(cancellationToken); var currentVersion = await externalFilesService.GetAdminChangeLogAsync(cancellationToken);
if (manager != null) if (manager != null)
{ {
if (!(manager.LatestVersionUsed < currentVersion.VersionNumber)) return currentVersion; if (!(manager.LatestVersionUsed < currentVersion.VersionNumber)) return currentVersion;
currentVersion.IsNewVersion = true; currentVersion.IsNewVersion = true;
manager.LatestVersionUsed = currentVersion.VersionNumber; manager.LatestVersionUsed = currentVersion.VersionNumber;
_repositoryWrapper.SetRepository<Manager>() repositoryWrapper.SetRepository<Manager>()
.Update(manager); .Update(manager);
await _repositoryWrapper.SaveChangesAsync(cancellationToken); await repositoryWrapper.SaveChangesAsync(cancellationToken);
} }
return currentVersion; return currentVersion;
@ -331,7 +317,7 @@ public class UserService : IUserService
public async Task<List<ApplicationRole>> GetRolesAsync(int page = 0, CancellationToken cancellationToken = default) public async Task<List<ApplicationRole>> GetRolesAsync(int page = 0, CancellationToken cancellationToken = default)
{ {
var roles = await _roleManager.Roles var roles = await roleManager.Roles
.Where(r => r.Name != "RootAdmin") .Where(r => r.Name != "RootAdmin")
.Skip(page * 15) .Skip(page * 15)
.Take(15) .Take(15)
@ -343,9 +329,9 @@ public class UserService : IUserService
{ {
IQueryable<ApplicationRole> roles; IQueryable<ApplicationRole> roles;
if (roleName != null) if (roleName != null)
roles = _roleManager.Roles.Where(r => r.Name != "RootAdmin" && r.Name != "Customer" && r.PersianName.Trim().ToLower().Contains(roleName)); roles = roleManager.Roles.Where(r => r.Name != "RootAdmin" && r.Name != "Customer" && r.PersianName.Trim().ToLower().Contains(roleName));
else else
roles = _roleManager.Roles.Where(r => r.Name != "RootAdmin" && r.Name != "Customer"); roles = roleManager.Roles.Where(r => r.Name != "RootAdmin" && r.Name != "Customer");
if (page != null) if (page != null)
roles = roles.Skip(page.Value * 15).Take(15); roles = roles.Skip(page.Value * 15).Take(15);
else else
@ -355,13 +341,13 @@ public class UserService : IUserService
public async Task<RoleActionRequestDto> GetRoleAsync(Guid roleId, CancellationToken cancellationToken = default) public async Task<RoleActionRequestDto> GetRoleAsync(Guid roleId, CancellationToken cancellationToken = default)
{ {
var role = (await _roleManager.FindByIdAsync(roleId.ToString())); var role = (await roleManager.FindByIdAsync(roleId.ToString()));
if (role == null) if (role == null)
throw new AppException("نقش پیدا نشد", ApiResultStatusCode.NotFound); throw new AppException("نقش پیدا نشد", ApiResultStatusCode.NotFound);
var roleDto = role.Adapt<RoleActionRequestDto>(); var roleDto = role.Adapt<RoleActionRequestDto>();
roleDto.RoleId = roleId; roleDto.RoleId = roleId;
roleDto.Permissions = (await _roleManager.GetClaimsAsync(role)) roleDto.Permissions = (await roleManager.GetClaimsAsync(role))
.Where(c => c.Type == CustomClaimType.Permission) .Where(c => c.Type == CustomClaimType.Permission)
.Select(c => c.Value) .Select(c => c.Value)
.ToList(); .ToList();
@ -380,12 +366,12 @@ public class UserService : IUserService
Description = request.Description, Description = request.Description,
Name = $"{request.EnglishName}" Name = $"{request.EnglishName}"
}; };
var createRoleResult = await _roleManager.CreateAsync(applicationRole); var createRoleResult = await roleManager.CreateAsync(applicationRole);
if (!createRoleResult.Succeeded) if (!createRoleResult.Succeeded)
throw new AppException(string.Join('|', createRoleResult.Errors)); throw new AppException(string.Join('|', createRoleResult.Errors));
foreach (var claim in request.Permissions) foreach (var claim in request.Permissions)
await _roleManager.AddClaimAsync(applicationRole, new Claim(CustomClaimType.Permission, claim)); await roleManager.AddClaimAsync(applicationRole, new Claim(CustomClaimType.Permission, claim));
return applicationRole; return applicationRole;
} }
@ -393,7 +379,7 @@ public class UserService : IUserService
{ {
if (request.EnglishName.IsNullOrEmpty()) if (request.EnglishName.IsNullOrEmpty())
throw new AppException("لطفا نام انگلیسی را وارد کنید"); throw new AppException("لطفا نام انگلیسی را وارد کنید");
var applicationRole = await _roleManager.FindByIdAsync(request.RoleId.ToString()); var applicationRole = await roleManager.FindByIdAsync(request.RoleId.ToString());
if (applicationRole == null) if (applicationRole == null)
throw new AppException("نقش پیدا نشد"); throw new AppException("نقش پیدا نشد");
@ -402,20 +388,20 @@ public class UserService : IUserService
applicationRole.Description = request.Description; applicationRole.Description = request.Description;
applicationRole.Name = $"{request.EnglishName}"; applicationRole.Name = $"{request.EnglishName}";
var createRoleResult = await _roleManager.UpdateAsync(applicationRole); var createRoleResult = await roleManager.UpdateAsync(applicationRole);
if (!createRoleResult.Succeeded) if (!createRoleResult.Succeeded)
throw new AppException(string.Join('|', createRoleResult.Errors)); throw new AppException(string.Join('|', createRoleResult.Errors));
var roleClaims = (await _roleManager.GetClaimsAsync(applicationRole)).Where(c => c.Type == CustomClaimType.Permission).ToList(); var roleClaims = (await roleManager.GetClaimsAsync(applicationRole)).Where(c => c.Type == CustomClaimType.Permission).ToList();
foreach (var roleClaim in roleClaims.ToList()) foreach (var roleClaim in roleClaims.ToList())
{ {
var removeResult = await _roleManager.RemoveClaimAsync(applicationRole, roleClaim); var removeResult = await roleManager.RemoveClaimAsync(applicationRole, roleClaim);
if (!removeResult.Succeeded) if (!removeResult.Succeeded)
throw new AppException(string.Join(" | ", removeResult.Errors.Select(e => e.Description))); throw new AppException(string.Join(" | ", removeResult.Errors.Select(e => e.Description)));
} }
foreach (var claim in request.Permissions) foreach (var claim in request.Permissions)
{ {
var addResult = await _roleManager.AddClaimAsync(applicationRole, new Claim(CustomClaimType.Permission, claim)); var addResult = await roleManager.AddClaimAsync(applicationRole, new Claim(CustomClaimType.Permission, claim));
if (!addResult.Succeeded) if (!addResult.Succeeded)
throw new AppException(string.Join(" | ", addResult.Errors.Select(e => e.Description))); throw new AppException(string.Join(" | ", addResult.Errors.Select(e => e.Description)));
} }
@ -425,18 +411,18 @@ public class UserService : IUserService
public async Task<bool> RemoveRoleAsync(Guid roleId, CancellationToken cancellationToken = default) public async Task<bool> RemoveRoleAsync(Guid roleId, CancellationToken cancellationToken = default)
{ {
var applicationRole = await _roleManager.FindByIdAsync(roleId.ToString()); var applicationRole = await roleManager.FindByIdAsync(roleId.ToString());
if (applicationRole == null) if (applicationRole == null)
throw new AppException("User not found", ApiResultStatusCode.NotFound); throw new AppException("User not found", ApiResultStatusCode.NotFound);
var claims = await _roleManager.GetClaimsAsync(applicationRole); var claims = await roleManager.GetClaimsAsync(applicationRole);
foreach (var claim in claims) foreach (var claim in claims)
await _roleManager.RemoveClaimAsync(applicationRole, claim); await roleManager.RemoveClaimAsync(applicationRole, claim);
var users = await _userManager.GetUsersInRoleAsync(applicationRole.Name); var users = await userManager.GetUsersInRoleAsync(applicationRole.Name);
foreach (var user in users) foreach (var user in users)
await _userManager.RemoveFromRoleAsync(user, applicationRole.Name); await userManager.RemoveFromRoleAsync(user, applicationRole.Name);
var removeResult = await _roleManager.DeleteAsync(applicationRole); var removeResult = await roleManager.DeleteAsync(applicationRole);
if (!removeResult.Succeeded) if (!removeResult.Succeeded)
throw new AppException(string.Join('|', removeResult.Errors.Select(e => e.Description))); throw new AppException(string.Join('|', removeResult.Errors.Select(e => e.Description)));
return true; return true;

View File

@ -1,18 +1,11 @@
namespace Netina.Core.Models.Api; namespace Netina.Core.Models.Api;
public class ApiResult public class ApiResult(bool isSuccess, ApiResultStatusCode statusCode, string message = null)
{ {
public ApiResult(bool isSuccess, ApiResultStatusCode statusCode, string message = null) public bool IsSuccess { get; set; } = isSuccess;
{ public ApiResultStatusCode StatusCode { get; set; } = statusCode;
IsSuccess = isSuccess;
StatusCode = statusCode;
Message = message ?? statusCode.ToDisplay();
}
public bool IsSuccess { get; set; }
public ApiResultStatusCode StatusCode { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)] [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string Message { get; set; } public string Message { get; set; } = message ?? statusCode.ToDisplay();
#region Implicit Operators #region Implicit Operators
@ -61,17 +54,12 @@ public class ApiResult
#endregion #endregion
} }
public class ApiResult<TData> : ApiResult public class ApiResult<TData>(bool isSuccess, ApiResultStatusCode statusCode, TData data, string message = null)
: ApiResult(isSuccess, statusCode, message)
where TData : class where TData : class
{ {
public ApiResult(bool isSuccess, ApiResultStatusCode statusCode, TData data, string message = null)
: base(isSuccess, statusCode, message)
{
Data = data;
}
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)] [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public TData Data { get; set; } public TData Data { get; set; } = data;
#region Implicit Operators #region Implicit Operators

View File

@ -7,12 +7,12 @@ public static class SiteMapUIds
public const string BlogCategories = "B5FF333DC4FF4BB4A309CE3AA32CE45A"; public const string BlogCategories = "B5FF333DC4FF4BB4A309CE3AA32CE45A";
public const string Pages = "B463B6C4CC53432C822D79934F528D3E"; public const string Pages = "B463B6C4CC53432C822D79934F528D3E";
public static List<string> AllSiteMapsUIds => new List<string> public static List<string> AllSiteMapsUIds =>
{ [
BlogCategories, BlogCategories,
Categories, Categories,
Blogs, Blogs,
Brands, Brands,
Pages Pages
}; ];
} }

View File

@ -4,6 +4,7 @@
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>
</PropertyGroup> </PropertyGroup>
@ -12,9 +13,9 @@
<PackageReference Include="AspNetCoreRateLimit.Redis" Version="2.0.0" /> <PackageReference Include="AspNetCoreRateLimit.Redis" Version="2.0.0" />
<PackageReference Include="Autofac.Extras.Quartz" Version="10.0.0" /> <PackageReference Include="Autofac.Extras.Quartz" Version="10.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.4" /> <PackageReference Include="SixLabors.ImageSharp" Version="3.1.5" />
<PackageReference Include="Quartz" Version="3.8.1" /> <PackageReference Include="Quartz" Version="3.13.0" />
<PackageReference Include="Syncfusion.Pdf.Net.Core" Version="24.1.41" /> <PackageReference Include="Syncfusion.Pdf.Net.Core" Version="27.1.50" />
</ItemGroup> </ItemGroup>
@ -26,7 +27,6 @@
<ItemGroup> <ItemGroup>
<Folder Include="CoreServices\WebSiteServices\" /> <Folder Include="CoreServices\WebSiteServices\" />
<Folder Include="EntityServices\ProductHandlers\" /> <Folder Include="EntityServices\ProductHandlers\" />
<Folder Include="EntityServices\ReviewHandlers\" />
<Folder Include="Models\Api\" /> <Folder Include="Models\Api\" />
<Folder Include="Models\Scraper\" /> <Folder Include="Models\Scraper\" />
<Folder Include="Utilities\" /> <Folder Include="Utilities\" />

View File

@ -3,20 +3,11 @@ using Quartz;
namespace Netina.Core.QuartzServices; namespace Netina.Core.QuartzServices;
public class JobScheduler public class JobScheduler(IScheduler scheduler, ILogger<JobScheduler> logger)
{ {
private readonly IScheduler _scheduler;
private readonly ILogger<JobScheduler> _logger;
public JobScheduler(IScheduler scheduler, ILogger<JobScheduler> logger)
{
_scheduler = scheduler;
_logger = logger;
}
public void Start() public void Start()
{ {
_scheduler.Start(); scheduler.Start();
IJobDetail job = JobBuilder.Create<SiteMapScheduledJob>() IJobDetail job = JobBuilder.Create<SiteMapScheduledJob>()
.WithIdentity("SiteMapJob", "admin") .WithIdentity("SiteMapJob", "admin")
@ -33,10 +24,10 @@ public class JobScheduler
DayOfWeek.Friday)) DayOfWeek.Friday))
.StartNow() .StartNow()
.Build(); .Build();
var offset = _scheduler.ScheduleJob(job, trigger); var offset = scheduler.ScheduleJob(job, trigger);
_logger.LogInformation($"======== Table Schedulers Set For {offset.Result.ToString()} IN {DateTime.Now.ToString()} ==========="); logger.LogInformation($"======== Table Schedulers Set For {offset.Result.ToString()} IN {DateTime.Now.ToString()} ===========");
} }
} }

View File

@ -3,20 +3,11 @@ using Quartz;
namespace Netina.Core.QuartzServices; namespace Netina.Core.QuartzServices;
public class SiteMapScheduledJob : IJob public class SiteMapScheduledJob(ILogger<SiteMapScheduledJob> logger, ISiteMapService siteMapService) : IJob
{ {
private readonly ILogger<SiteMapScheduledJob> _logger;
private readonly ISiteMapService _siteMapService;
public SiteMapScheduledJob(ILogger<SiteMapScheduledJob> logger,ISiteMapService siteMapService)
{
_logger = logger;
_siteMapService = siteMapService;
}
public async Task Execute(IJobExecutionContext context) public async Task Execute(IJobExecutionContext context)
{ {
await _siteMapService.CreateSiteMapAsync(); await siteMapService.CreateSiteMapAsync();
_logger.LogInformation($"Site Map Job Done At : {DateTime.Now}"); logger.LogInformation($"Site Map Job Done At : {DateTime.Now}");
} }
} }

View File

@ -1,8 +1,23 @@
namespace Netina.Domain.CommandQueries.Commands; namespace Netina.Domain.CommandQueries.Commands;
public sealed record CreateBrandCommand(string PersianName,string EnglishName, string Description , bool HasSpecialPage , string PageUrl, List<StorageFileSDto> Files) : IRequest<Guid>; public sealed record CreateBrandCommand(string PersianName,
string EnglishName,
string Description ,
bool HasSpecialPage ,
string PageUrl,
List<StorageFileSDto> Files,
Dictionary<string, string> Faqs,
Dictionary<string, string> MetaTags) : IRequest<Guid>;
public sealed record UpdateBrandCommand(Guid Id,string PersianName, string EnglishName, string Description, bool HasSpecialPage, string PageUrl, List<StorageFileSDto> Files) : IRequest<bool>; public sealed record UpdateBrandCommand(Guid Id,
string PersianName,
string EnglishName,
string Description,
bool HasSpecialPage,
string PageUrl,
List<StorageFileSDto> Files,
Dictionary<string, string> Faqs,
Dictionary<string, string> MetaTags) : IRequest<bool>;
public sealed record DeleteBrandCommand(Guid Id) : IRequest<bool>; public sealed record DeleteBrandCommand(Guid Id) : IRequest<bool>;

View File

@ -0,0 +1,27 @@
namespace Netina.Domain.CommandQueries.Commands;
public sealed record CreateCommentCommand(
string Title,
string Content,
float Rate,
bool IsBuyer,
bool IsAdmin,
Guid? ParentId,
Guid? BlogId = null,
Guid? ProductId = null,
Guid? UserId = null) : IRequest<Guid>;
public sealed record UpdateCommentCommand(
Guid Id,
string Title,
string Content,
float Rate,
bool IsBuyer,
bool IsAdmin,
Guid? ParentId,
Guid? BlogId = null,
Guid? ProductId = null,
Guid? UserId = null) : IRequest<Guid>;
public sealed record ConfirmCommentCommand(Guid Id) : IRequest<Guid>;
public sealed record DeleteCommentCommand(Guid Id) : IRequest<Guid>;

View File

@ -21,7 +21,8 @@ bool IsForInvitation,
bool IsSpecialOffer, bool IsSpecialOffer,
bool IsForFirstPurchase, bool IsForFirstPurchase,
Guid ProductId, Guid ProductId,
Guid CategoryId) : IRequest<DiscountLDto>; Guid CategoryId,
Guid BrandId) : IRequest<DiscountLDto>;
public sealed record UpdateDiscountCommand( public sealed record UpdateDiscountCommand(
Guid Id, Guid Id,
@ -46,9 +47,11 @@ public sealed record UpdateDiscountCommand(
bool IsSpecialOffer, bool IsSpecialOffer,
bool IsForFirstPurchase, bool IsForFirstPurchase,
Guid ProductId, Guid ProductId,
Guid CategoryId) : IRequest<bool>; Guid CategoryId,
Guid BrandId) : IRequest<bool>;
public sealed record DeleteDiscountCommand(Guid Id) : IRequest<bool>; public sealed record DeleteDiscountCommand(Guid Id) : IRequest<bool>;
public sealed record CalculateOrderDiscountCommand(string DiscountCode, Order Order) : IRequest<double>; public sealed record CalculateOrderDiscountCommand(string DiscountCode, Order Order) : IRequest<double>;
public sealed record CheckUserDiscountFirstUseCommand(string DiscountCode) : IRequest<bool>;

View File

@ -0,0 +1,15 @@
namespace Netina.Domain.CommandQueries.Commands;
public record CreateFaqCommand(
Dictionary<string, string> Faqs,
string Slug,
string Title) : IRequest<bool>;
public record DeleteFaqCommand(Guid Id) : IRequest<bool>;
public record UpdateFaqCommand(
Guid Id,
Dictionary<string, string> Faqs,
string Slug,
string Title) : IRequest<bool>;

View File

@ -6,7 +6,7 @@ public sealed record CheckOrderBagCommand(List<CheckOrderBagRequestItem> OrderBa
public sealed record AddToOrderBagCommand(List<OrderBagRequestDto> RequestDtos) : IRequest<OrderSDto>; public sealed record AddToOrderBagCommand(List<OrderBagRequestDto> RequestDtos) : IRequest<OrderSDto>;
public sealed record RemoveFromOrderBagCommand(List<OrderBagRequestDto> RequestDtos) : IRequest<OrderSDto>; public sealed record RemoveFromOrderBagCommand(List<OrderBagRequestDto> RequestDtos) : IRequest<OrderSDto>;
public sealed record SubmitDiscountCommand(Guid OrderId,string DiscountCode) : IRequest<OrderSDto>; public sealed record SubmitDiscountActionCommand(Guid OrderId,string? DiscountCode) : IRequest<OrderSDto>;
public sealed record SubmitOrderDeliveryCommand(Guid AddressId, Guid OrderId, Guid ShippingId) : IRequest<OrderSDto>; public sealed record SubmitOrderDeliveryCommand(Guid AddressId, Guid OrderId, Guid ShippingId) : IRequest<OrderSDto>;
public sealed record SubmitOrderBagCommand(List<OrderBagRequestDto> RequestDtos) : IRequest<OrderSDto>; public sealed record SubmitOrderBagCommand(List<OrderBagRequestDto> RequestDtos) : IRequest<OrderSDto>;

View File

@ -4,6 +4,7 @@ public sealed record CreateBaseOrderCommand(Guid UserId) : IRequest<Order>;
public sealed record CalculateOrderCommand(Guid OrderId , bool NamoosiCalculate = false) : IRequest<Order>; public sealed record CalculateOrderCommand(Guid OrderId , bool NamoosiCalculate = false) : IRequest<Order>;
public sealed record ConfirmOrderStepCommand(Guid OrderId , OrderStatus NextOrderStatus,string? TrackingCode) : IRequest<bool>; public sealed record ConfirmOrderStepCommand(Guid OrderId , OrderStatus NextOrderStatus,string? TrackingCode) : IRequest<bool>;
public sealed record CancelOrderStepCommand(Guid OrderId) : IRequest<bool>;
public sealed record GetOrderInvoiceCommand(Guid OrderId) : IRequest<byte[]>; public sealed record GetOrderInvoiceCommand(Guid OrderId) : IRequest<byte[]>;
public sealed record DeleteOrderCommand(Guid OrderId) : IRequest<bool>; public sealed record DeleteOrderCommand(Guid OrderId) : IRequest<bool>;

View File

@ -5,7 +5,9 @@ public sealed record CreateProductCategoryCommand(
string Description, string Description,
bool IsMain, bool IsMain,
Guid ParentId, Guid ParentId,
List<StorageFileSDto> Files) : IRequest<Guid>; List<StorageFileSDto> Files,
Dictionary<string, string> Faqs,
Dictionary<string, string> MetaTags) : IRequest<Guid>;
public sealed record UpdateProductCategoryCommand( public sealed record UpdateProductCategoryCommand(
Guid Id, Guid Id,
@ -13,6 +15,8 @@ public sealed record UpdateProductCategoryCommand(
string Description, string Description,
bool IsMain, bool IsMain,
Guid ParentId, Guid ParentId,
List<StorageFileSDto> Files) : IRequest<bool>; List<StorageFileSDto> Files,
Dictionary<string, string> Faqs,
Dictionary<string, string> MetaTags) : IRequest<bool>;
public sealed record DeleteProductCategoryCommand(Guid Id) : IRequest<bool>; public sealed record DeleteProductCategoryCommand(Guid Id) : IRequest<bool>;

View File

@ -1,24 +1,26 @@
namespace Netina.Domain.CommandQueries.Commands; namespace Netina.Domain.CommandQueries.Commands;
public sealed record CreateProductCommand( public sealed record CreateProductCommand(
string PersianName, string PersianName,
string EnglishName, string EnglishName,
string Summery, string Summery,
string ExpertCheck, string ExpertCheck,
string Tags, string Tags,
string Warranty, string Warranty,
bool BeDisplayed, bool BeDisplayed,
double Cost, double Cost,
double PackingCost, double PackingCost,
int Stock, int Stock,
bool HasExpressDelivery, bool HasExpressDelivery,
int MaxOrderCount, int MaxOrderCount,
bool IsSpecialOffer, bool IsSpecialOffer,
Guid BrandId, Guid BrandId,
Guid CategoryId, Guid CategoryId,
DiscountSDto SpecialOffer, DiscountSDto SpecialOffer,
List<SpecificationSDto> Specifications, List<SpecificationSDto> Specifications,
List<StorageFileSDto> Files):IRequest<ProductLDto>; List<StorageFileSDto> Files,
Dictionary<string, string> Faqs,
Dictionary<string, string> MetaTags) : IRequest<ProductLDto>;
public sealed record UpdateProductCommand( public sealed record UpdateProductCommand(
Guid Id, Guid Id,
@ -39,9 +41,13 @@ public sealed record UpdateProductCommand(
Guid CategoryId, Guid CategoryId,
DiscountSDto SpecialOffer, DiscountSDto SpecialOffer,
List<SpecificationSDto> Specifications, List<SpecificationSDto> Specifications,
List<StorageFileSDto> Files) : IRequest<bool>; List<StorageFileSDto> Files,
Dictionary<string, string> Faqs,
Dictionary<string, string> MetaTags) : IRequest<bool>;
public sealed record ChangeProductDisplayedCommand(Guid Id,bool BeDisplayed) : IRequest<bool>; public sealed record ChangeProductDisplayedCommand(Guid Id, bool BeDisplayed) : IRequest<bool>;
public sealed record ChangeProductCostCommand(Guid Id, double Cost) : IRequest<bool>;
public sealed record DeleteProductCommand(Guid Id) : IRequest<bool>; public sealed record DeleteProductCommand(Guid Id) : IRequest<bool>;

View File

@ -1,6 +0,0 @@
namespace Netina.Domain.CommandQueries.Commands;
public sealed record CreateReviewCommand(string Title, string Comment, float Rate, bool IsBuyer, Guid ProductId, Guid UserId) : IRequest<ReviewSDto>;
public sealed record UpdateReviewCommand(Guid Id,string Title, string Comment, float Rate, bool IsBuyer, Guid ProductId, Guid UserId): IRequest<bool>;
public sealed record ConfirmReviewCommand(Guid Id) : IRequest<bool>;
public sealed record DeleteReviewCommand(Guid Id) : IRequest<bool>;

View File

@ -0,0 +1,33 @@
namespace Netina.Domain.CommandQueries.Commands;
public sealed record CreateSubProductCommand(
Guid ParentId,
ProductDiversity Diversity,
string DiversityValue,
string DiversitySecondaryValue,
string DiversityDescription,
string PersianName,
double Cost,
double PackingCost,
int Stock,
bool HasExpressDelivery,
int MaxOrderCount,
List<StorageFileSDto> Files) : IRequest<Guid>;
public sealed record UpdateSubProductCommand(
Guid Id,
Guid ParentId,
ProductDiversity Diversity,
string DiversityValue,
string DiversitySecondaryValue,
string DiversityDescription,
string PersianName,
double Cost,
double PackingCost,
int Stock,
bool HasExpressDelivery,
int MaxOrderCount,
List<StorageFileSDto> Files) : IRequest<Guid>;
public sealed record DeleteSubProductCommand(Guid Id) : IRequest<bool>;

View File

@ -0,0 +1,4 @@
namespace Netina.Domain.CommandQueries.Queries;
public record GetCommentsQuery(int Page = 0,int Count = Refers.SizeM ,Guid? ProductId = null, Guid? BlogId = null) : IRequest<List<CommentSDto>>;
public record GetCommentQuery(Guid Id) : IRequest<CommentLDto>;

View File

@ -0,0 +1,3 @@
namespace Netina.Domain.CommandQueries.Queries;
public record GetCustomersQuery(int Page = 0, int Count = Refers.SizeM) : IRequest<List<CustomerSDto>>;

View File

@ -0,0 +1,4 @@
namespace Netina.Domain.CommandQueries.Queries;
public record GetFaqQuery(Guid? Id,string? Slug) : IRequest<BaseFaq>;
public record GetFaqsQuery(int Page , int Count = 0) : IRequest<List<BaseFaq>>;

View File

@ -4,4 +4,4 @@ public sealed record GetOrderLDtoQuery(Guid Id) : IRequest<OrderLDto>;
public sealed record GetUserOrdersQuery(Guid CustomerId = default) : IRequest<List<OrderSDto>>; public sealed record GetUserOrdersQuery(Guid CustomerId = default) : IRequest<List<OrderSDto>>;
public sealed record GetOrderQuery(Guid Id) : IRequest<Order>; public sealed record GetOrderQuery(Guid Id) : IRequest<Order>;
public sealed record GetOrdersQuery(OrderQueryDateFilter? DateFilter, OrderStatus? OrderStatus,long? SelectedDate,string? FactorCode, int Page = 0) : IRequest<List<OrderSDto>>; public sealed record GetOrdersQuery(OrderQueryDateFilter? DateFilter, OrderStatus? OrderStatus,long? SelectedDate,string? FactorCode,bool OrderBags, int Page = 0) : IRequest<List<OrderSDto>>;

View File

@ -7,7 +7,7 @@ public sealed record GetProductsQuery(
bool? IsActive, bool? IsActive,
bool? SpecialOffer, bool? SpecialOffer,
int Page = 0 , int Page = 0 ,
string? ProductName = default, string? ProductName = null,
QuerySortBy SortBy = QuerySortBy.None , QuerySortBy SortBy = QuerySortBy.None ,
Guid CategoryId = default , Guid CategoryId = default ,
double MinPrice = -1 , double MinPrice = -1 ,

View File

@ -1,4 +0,0 @@
namespace Netina.Domain.CommandQueries.Queries;
public record GetReviewsQuery(int Page = 0) : IRequest<List<ReviewSDto>>;
public record GetReviewQuery(Guid Id) : IRequest<ReviewLDto>;

Some files were not shown because too many files have changed in this diff Show More